Merge tracemonkey to mozilla-central.

This commit is contained in:
Robert Sayre 2010-05-06 08:50:41 -04:00
Родитель 08b5017ae1 15be135941
Коммит c5b2bbeb04
76 изменённых файлов: 1021 добавлений и 1050 удалений

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

@ -3101,10 +3101,10 @@ nsXULPrototypeScript::Compile(const PRUnichar* aText,
//
// Compiling it using (for example) the first document's global
// object would cause JS to keep a reference via the __proto__ or
// __parent__ pointer to the first document's global. If that
// happened, our script object would reference the first document,
// and the first document would indirectly reference the prototype
// document because it keeps the prototype cache alive. Circularity!
// parent pointer to the first document's global. If that happened,
// our script object would reference the first document, and the
// first document would indirectly reference the prototype document
// because it keeps the prototype cache alive. Circularity!
nsresult rv;
// Use the prototype document's special context

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

@ -1266,3 +1266,65 @@ nsDOMWindowUtils::GetVisitedDependentComputedStyle(
return rv;
}
NS_IMETHODIMP
nsDOMWindowUtils::GetParent()
{
// This wasn't privileged in the past, but better to expose less than more.
if (!IsUniversalXPConnectCapable()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsIXPConnect> xpc = nsContentUtils::XPConnect();
// get the xpconnect native call context
nsAXPCNativeCallContext *cc = nsnull;
xpc->GetCurrentNativeCallContext(&cc);
if(!cc)
return NS_ERROR_FAILURE;
// Get JSContext of current call
JSContext* cx;
nsresult rv = cc->GetJSContext(&cx);
if(NS_FAILED(rv) || !cx)
return NS_ERROR_FAILURE;
// get place for return value
jsval *rval = nsnull;
rv = cc->GetRetValPtr(&rval);
if(NS_FAILED(rv) || !rval)
return NS_ERROR_FAILURE;
// get argc and argv and verify arg count
PRUint32 argc;
rv = cc->GetArgc(&argc);
if(NS_FAILED(rv))
return NS_ERROR_FAILURE;
if(argc != 1)
return NS_ERROR_XPC_NOT_ENOUGH_ARGS;
jsval* argv;
rv = cc->GetArgvPtr(&argv);
if(NS_FAILED(rv) || !argv)
return NS_ERROR_FAILURE;
// first argument must be an object
if(JSVAL_IS_PRIMITIVE(argv[0]))
return NS_ERROR_XPC_BAD_CONVERT_JS;
JSObject *parent = JS_GetParent(cx, JSVAL_TO_OBJECT(argv[0]));
*rval = OBJECT_TO_JSVAL(parent);
// Outerize if necessary. Embrace the ugliness!
JSClass *clasp = JS_GetClass(cx, parent);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
if (JSObjectOp outerize = xclasp->outerObject)
*rval = OBJECT_TO_JSVAL(outerize(cx, parent));
}
cc->SetReturnValueWasSet(PR_TRUE);
return NS_OK;
}

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

@ -53,7 +53,7 @@ interface nsIDOMEvent;
interface nsITransferable;
interface nsIQueryContentEventResult;
[scriptable, uuid(22a62b54-bcf5-422a-a329-fed4de5e78b2)]
[scriptable, uuid(352ff0af-bb38-496a-a067-b54771168d6d)]
interface nsIDOMWindowUtils : nsISupports {
/**
@ -655,4 +655,12 @@ interface nsIDOMWindowUtils : nsISupports {
AString getVisitedDependentComputedStyle(in nsIDOMElement aElement,
in AString aPseudoElement,
in AString aPropertyName);
/**
* Returns the parent of obj.
*
* @param obj The JavaScript object whose parent is to be gotten.
* @return the parent.
*/
void getParent(/* obj */);
};

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

@ -77,21 +77,6 @@ function inspect(obj) {
return;
}
print("* Object type: "+typeof obj+"\n");
if (typeof obj != "xml") {
print("* Parent chain: ");
try {
var parent = obj.__parent__;
while(parent) {
try {
print(parent);
}
catch(e) { dump("(?)"); }
finally { dump(" "); }
parent = parent.__parent__;
}
} catch(e) { dump("...(?)"); }
print("\n");
}
switch(typeof obj) {
case "object":
print("* Prototype chain: ");

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

@ -3946,16 +3946,18 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj, JSObject* fieldsObj
// Create a hash of FieldInfo objects to stash on the type object.
FieldInfoHash* fields(new FieldInfoHash);
if (!fields || !fields->init(len)) {
delete fields;
JS_ReportOutOfMemory(cx);
delete fields;
return JS_FALSE;
}
// Stash the FieldInfo hash in a reserved slot now, for GC safety of its
// constituents.
if (!JS_SetReservedSlot(cx, typeObj, SLOT_FIELDINFO,
PRIVATE_TO_JSVAL(fields)))
PRIVATE_TO_JSVAL(fields))) {
delete fields;
return JS_FALSE;
}
// Process the field types.
size_t structSize, structAlign;

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

@ -1345,7 +1345,6 @@ static JSStdName standard_class_names[] = {
static JSStdName object_prototype_names[] = {
/* Object.prototype properties (global delegates to Object.prototype). */
{js_InitObjectClass, EAGER_ATOM(proto), NULL},
{js_InitObjectClass, EAGER_ATOM(parent), NULL},
#if JS_HAS_TOSOURCE
{js_InitObjectClass, EAGER_ATOM(toSource), NULL},
#endif
@ -4237,12 +4236,11 @@ js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, jsval *vp)
fs = (JSFunctionSpec *) JSVAL_TO_PRIVATE(fsv);
JS_ASSERT((~fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) == 0);
/*
* We know that vp[2] is valid because JS_DefineFunctions, which is our
* only (indirect) referrer, defined us as requiring at least one argument
* (notice how it passes fs->nargs + 1 as the next-to-last argument to
* JS_DefineFunction).
*/
if (argc < 1) {
js_ReportMissingArg(cx, vp, 0);
return JS_FALSE;
}
if (JSVAL_IS_PRIMITIVE(vp[2])) {
/*
* Make sure that this is an object or null, as required by the generic
@ -4267,15 +4265,9 @@ js_generic_fast_native_method_dispatcher(JSContext *cx, uintN argc, jsval *vp)
*/
if (!js_ComputeThis(cx, vp + 2))
return JS_FALSE;
/*
* Protect against argc underflowing. By calling js_ComputeThis, we made
* it as if the static was called with one parameter, the explicit |this|
* object.
*/
if (argc != 0) {
/* Clear the last parameter in case too few arguments were passed. */
vp[2 + --argc] = JSVAL_VOID;
}
/* Clear the last parameter in case too few arguments were passed. */
vp[2 + --argc] = JSVAL_VOID;
native =
#ifdef JS_TRACER
@ -4301,12 +4293,11 @@ js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
JS_ASSERT((fs->flags & (JSFUN_FAST_NATIVE | JSFUN_GENERIC_NATIVE)) ==
JSFUN_GENERIC_NATIVE);
/*
* We know that argv[0] is valid because JS_DefineFunctions, which is our
* only (indirect) referrer, defined us as requiring at least one argument
* (notice how it passes fs->nargs + 1 as the next-to-last argument to
* JS_DefineFunction).
*/
if (argc < 1) {
js_ReportMissingArg(cx, argv - 2, 0);
return JS_FALSE;
}
if (JSVAL_IS_PRIMITIVE(argv[0])) {
/*
* Make sure that this is an object or null, as required by the generic
@ -4334,15 +4325,8 @@ js_generic_native_method_dispatcher(JSContext *cx, JSObject *obj,
js_GetTopStackFrame(cx)->thisv = argv[-1];
JS_ASSERT(cx->fp->argv == argv);
/*
* Protect against argc underflowing. By calling js_ComputeThis, we made
* it as if the static was called with one parameter, the explicit |this|
* object.
*/
if (argc != 0) {
/* Clear the last parameter in case too few arguments were passed. */
argv[--argc] = JSVAL_VOID;
}
/* Clear the last parameter in case too few arguments were passed. */
argv[--argc] = JSVAL_VOID;
return fs->call(cx, JSVAL_TO_OBJECT(argv[-1]), argc, argv, rval);
}

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

@ -57,7 +57,8 @@
* setters, it's updated automatically by setDenseArrayLength() and
* setDenseArrayCapacity(). There are also no explicit getters, the only
* user is TraceRecorder which can access it directly because it's a
* friend.
* friend. The function isDenseArrayMinLenCapOk() checks that it is set
* correctly; a call to it should be put in an assertion at use points.
*
* In dense mode, holes in the array are represented by JSVAL_HOLE. The final
* slot in fslots is unused.
@ -1273,8 +1274,7 @@ JSClass js_ArrayClass = {
"Array",
JSCLASS_HAS_RESERVED_SLOTS(2) |
JSCLASS_HAS_CACHED_PROTO(JSProto_Array) |
JSCLASS_NEW_ENUMERATE |
JSCLASS_CONSTRUCT_PROTOTYPE,
JSCLASS_NEW_ENUMERATE,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_EnumerateStub, JS_ResolveStub, js_TryValueOf, array_finalize,
array_getObjectOps, NULL, NULL, NULL,

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

@ -147,7 +147,6 @@ const char *const js_common_atom_names[] = {
js_name_str, /* nameAtom */
js_next_str, /* nextAtom */
js_noSuchMethod_str, /* noSuchMethodAtom */
js_parent_str, /* parentAtom */
js_proto_str, /* protoAtom */
js_set_str, /* setAtom */
js_stack_str, /* stackAtom */
@ -220,7 +219,6 @@ const char js_name_str[] = "name";
const char js_next_str[] = "next";
const char js_noSuchMethod_str[] = "__noSuchMethod__";
const char js_object_str[] = "object";
const char js_parent_str[] = "__parent__";
const char js_proto_str[] = "__proto__";
const char js_setter_str[] = "setter";
const char js_set_str[] = "set";

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

@ -259,7 +259,6 @@ struct JSAtomState {
JSAtom *nameAtom;
JSAtom *nextAtom;
JSAtom *noSuchMethodAtom;
JSAtom *parentAtom;
JSAtom *protoAtom;
JSAtom *setAtom;
JSAtom *stackAtom;
@ -388,7 +387,6 @@ extern const char js_namespace_str[];
extern const char js_next_str[];
extern const char js_noSuchMethod_str[];
extern const char js_object_str[];
extern const char js_parent_str[];
extern const char js_proto_str[];
extern const char js_ptagc_str[];
extern const char js_qualifier_str[];

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

@ -832,10 +832,9 @@ struct JSRuntime {
void *gcExtraRootsData;
/*
* Used to serialize cycle checks when setting __proto__ or __parent__ by
* requesting the GC handle the required cycle detection. If the GC hasn't
* been poked, it won't scan for garbage. This member is protected by
* rt->gcLock.
* Used to serialize cycle checks when setting __proto__ by requesting the
* GC handle the required cycle detection. If the GC hasn't been poked, it
* won't scan for garbage. This member is protected by rt->gcLock.
*/
JSSetSlotRequest *setSlotRequests;

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

@ -49,15 +49,14 @@
#define TYPEOF(cx,v) (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v))
using namespace js;
static char dempty[] = "<null>";
static char *
jsdtrace_fun_classname(const JSFunction *fun)
{
return (fun &&
!FUN_INTERPRETED(fun) &&
!(fun->flags & JSFUN_TRCINFO) &&
FUN_CLASP(fun))
return (fun && !FUN_INTERPRETED(fun) && !(fun->flags & JSFUN_TRCINFO) && FUN_CLASP(fun))
? (char *)FUN_CLASP(fun)->name
: dempty;
}
@ -65,9 +64,7 @@ jsdtrace_fun_classname(const JSFunction *fun)
static char *
jsdtrace_filename(JSStackFrame *fp)
{
return (fp && fp->script && fp->script->filename)
? (char *)fp->script->filename
: dempty;
return (fp && fp->script && fp->script->filename) ? (char *)fp->script->filename : dempty;
}
static int
@ -79,7 +76,7 @@ jsdtrace_fun_linenumber(JSContext *cx, const JSFunction *fun)
return 0;
}
int
static int
jsdtrace_frame_linenumber(JSContext *cx, JSStackFrame *fp)
{
if (fp && fp->regs)
@ -138,13 +135,10 @@ jsdtrace_jsvaltovoid(JSContext *cx, const jsval argval)
static char *
jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
{
JSAtom *atom;
char *name;
if (!fun)
return dempty;
atom = fun->atom;
JSAtom *atom = fun->atom;
if (!atom) {
/*
* TODO: maybe do more work here to figure out the name of the property
@ -154,7 +148,7 @@ jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
return dempty;
}
name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom));
char *name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom));
return name ? name : dempty;
}
@ -166,117 +160,85 @@ jsdtrace_fun_name(JSContext *cx, const JSFunction *fun)
* a number of usually unused lines of code would cause.
*/
void
jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, const JSFunction *fun)
DTrace::enterJSFunImpl(JSContext *cx, JSStackFrame *fp, const JSFunction *fun)
{
JAVASCRIPT_FUNCTION_ENTRY(
jsdtrace_filename(fp),
jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun)
);
JAVASCRIPT_FUNCTION_ENTRY(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun));
}
void
jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
JSFunction *fun)
DTrace::handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, JSFunction *fun)
{
JAVASCRIPT_FUNCTION_INFO(
jsdtrace_filename(fp),
jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun),
jsdtrace_fun_linenumber(cx, fun),
jsdtrace_filename(dfp),
jsdtrace_frame_linenumber(cx, dfp)
);
JAVASCRIPT_FUNCTION_INFO(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun),
jsdtrace_filename(dfp), jsdtrace_frame_linenumber(cx, dfp));
}
void
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsuint argc, jsval *argv)
DTrace::handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun, jsuint argc,
jsval *argv)
{
JAVASCRIPT_FUNCTION_ARGS(
jsdtrace_filename(fp),
jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun),
argc, (void *)argv,
(argc > 0) ? jsdtrace_jsvaltovoid(cx, argv[0]) : 0,
(argc > 1) ? jsdtrace_jsvaltovoid(cx, argv[1]) : 0,
(argc > 2) ? jsdtrace_jsvaltovoid(cx, argv[2]) : 0,
(argc > 3) ? jsdtrace_jsvaltovoid(cx, argv[3]) : 0,
(argc > 4) ? jsdtrace_jsvaltovoid(cx, argv[4]) : 0
);
JAVASCRIPT_FUNCTION_ARGS(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), argc, (void *)argv,
(argc > 0) ? jsdtrace_jsvaltovoid(cx, argv[0]) : 0,
(argc > 1) ? jsdtrace_jsvaltovoid(cx, argv[1]) : 0,
(argc > 2) ? jsdtrace_jsvaltovoid(cx, argv[2]) : 0,
(argc > 3) ? jsdtrace_jsvaltovoid(cx, argv[3]) : 0,
(argc > 4) ? jsdtrace_jsvaltovoid(cx, argv[4]) : 0);
}
void
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval *rval)
DTrace::handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval)
{
JAVASCRIPT_FUNCTION_RVAL(
jsdtrace_filename(fp),
jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun),
jsdtrace_fun_linenumber(cx, fun),
(void *)rval,
jsdtrace_jsvaltovoid(cx, *rval)
);
JAVASCRIPT_FUNCTION_RVAL(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun), jsdtrace_fun_linenumber(cx, fun),
NULL, jsdtrace_jsvaltovoid(cx, rval));
}
void
jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
DTrace::handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun)
{
JAVASCRIPT_FUNCTION_RETURN(
jsdtrace_filename(fp),
jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun)
);
JAVASCRIPT_FUNCTION_RETURN(jsdtrace_filename(fp), jsdtrace_fun_classname(fun),
jsdtrace_fun_name(cx, fun));
}
void
jsdtrace_object_create_start(JSStackFrame *fp, JSClass *clasp)
DTrace::ObjectCreationScope::handleCreationStart()
{
JAVASCRIPT_OBJECT_CREATE_START(jsdtrace_filename(fp), (char *)clasp->name);
}
void
jsdtrace_object_create_done(JSStackFrame *fp, JSClass *clasp)
DTrace::ObjectCreationScope::handleCreationEnd()
{
JAVASCRIPT_OBJECT_CREATE_DONE(jsdtrace_filename(fp), (char *)clasp->name);
}
void
jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj)
DTrace::ObjectCreationScope::handleCreationImpl(JSObject *obj)
{
JAVASCRIPT_OBJECT_CREATE(
jsdtrace_filename(cx->fp),
(char *)clasp->name,
(uintptr_t)obj,
jsdtrace_frame_linenumber(cx, cx->fp)
);
JAVASCRIPT_OBJECT_CREATE(jsdtrace_filename(cx->fp), (char *)clasp->name, (uintptr_t)obj,
jsdtrace_frame_linenumber(cx, cx->fp));
}
void
jsdtrace_object_finalize(JSObject *obj)
DTrace::finalizeObjectImpl(JSObject *obj)
{
JSClass *clasp;
clasp = obj->getClass();
JSClass *clasp = obj->getClass();
/* the first arg is NULL - reserved for future use (filename?) */
JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
}
void
jsdtrace_execute_start(JSScript *script)
DTrace::ExecutionScope::startExecution()
{
JAVASCRIPT_EXECUTE_START(
script->filename ? (char *)script->filename : dempty,
script->lineno
);
JAVASCRIPT_EXECUTE_START(script->filename ? (char *)script->filename : dempty,
script->lineno);
}
void
jsdtrace_execute_done(JSScript *script)
DTrace::ExecutionScope::endExecution()
{
JAVASCRIPT_EXECUTE_DONE(
script->filename ? (char *)script->filename : dempty,
script->lineno
);
JAVASCRIPT_EXECUTE_DONE(script->filename ? (char *)script->filename : dempty, script->lineno);
}

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

@ -42,126 +42,139 @@
#ifndef _JSDTRACEF_H
#define _JSDTRACEF_H
JS_BEGIN_EXTERN_C
extern void
jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, const JSFunction *fun);
extern void
jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
const JSFunction *fun);
extern void
jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsuint argc, jsval *argv);
extern void
jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsval rval);
extern void
jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, const JSFunction *fun);
extern void
jsdtrace_object_create_start(JSStackFrame *fp, const JSClass *clasp);
extern void
jsdtrace_object_create_done(JSStackFrame *fp, const JSClass *clasp);
extern void
jsdtrace_object_create(JSContext *cx, const JSClass *clasp, const JSObject *obj);
extern void
jsdtrace_object_finalize(const JSObject *obj);
extern void
jsdtrace_execute_start(const JSScript *script);
extern void
jsdtrace_execute_done(const JSScript *script);
JS_END_EXTERN_C
namespace js {
class DTrace {
static void enterJSFunImpl(JSContext *cx, JSStackFrame *fp, const JSFunction *fun);
static void handleFunctionInfo(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp,
JSFunction *fun);
static void handleFunctionArgs(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsuint argc, jsval *argv);
static void handleFunctionRval(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval);
static void handleFunctionReturn(JSContext *cx, JSStackFrame *fp, JSFunction *fun);
static void finalizeObjectImpl(JSObject *obj);
public:
/*
* If |lval| is provided to the enter/exit methods, it is tested to see if
* it is a function as a predicate to the dtrace event emission.
*/
static void enterJSFun(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
static void enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun,
JSStackFrame *dfp, jsuint argc, jsval *argv, jsval *lval = NULL);
static void exitJSFun(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsval rval, jsval *lval = NULL);
static void exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval,
jsval *lval = NULL);
static void finalizeObject(const JSObject *obj);
static void finalizeObject(JSObject *obj);
class ExecutionScope {
const JSScript *script;
void startExecution();
void endExecution();
public:
explicit ExecutionScope(const JSScript *script) : script(script) { startExecution(); }
~ExecutionScope() { endExecution(); }
explicit ExecutionScope(JSScript *script);
~ExecutionScope();
};
class ObjectCreationScope {
JSContext * const cx;
JSStackFrame * const fp;
JSClass * const clasp;
void handleCreationStart();
void handleCreationImpl(JSObject *obj);
void handleCreationEnd();
public:
ObjectCreationScope(JSContext *cx, JSStackFrame *fp, JSClass *clasp);
void handleCreation(JSObject *obj);
~ObjectCreationScope();
};
};
inline void
DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
JSStackFrame *dfp, jsuint argc, jsval *argv, jsval *lval)
DTrace::enterJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, JSStackFrame *dfp,
jsuint argc, jsval *argv, jsval *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || VALUE_IS_FUNCTION(cx, *lval)) {
if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED())
jsdtrace_function_entry(cx, fp, fun);
enterJSFunImpl(cx, fp, fun);
if (JAVASCRIPT_FUNCTION_INFO_ENABLED())
jsdtrace_function_info(cx, fp, dfp, fun);
handleFunctionInfo(cx, fp, dfp, fun);
if (JAVASCRIPT_FUNCTION_ARGS_ENABLED())
jsdtrace_function_args(cx, fp, fun, argc, argv);
handleFunctionArgs(cx, fp, fun, argc, argv);
}
#endif
}
inline void
DTrace::exitJSFun(JSContext *cx, JSStackFrame *fp, const JSFunction *fun,
jsval rval, jsval *lval)
DTrace::exitJSFun(JSContext *cx, JSStackFrame *fp, JSFunction *fun, jsval rval, jsval *lval)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (!lval || VALUE_IS_FUNCTION(cx, *lval)) {
if (JAVASCRIPT_FUNCTION_RVAL_ENABLED())
jsdtrace_function_rval(cx, fp, fun, rval);
handleFunctionRval(cx, fp, fun, rval);
if (JAVASCRIPT_FUNCTION_RETURN_ENABLED())
jsdtrace_function_return(cx, fp, fun);
handleFunctionReturn(cx, fp, fun);
}
#endif
}
inline void
DTrace::finalizeObject(const JSObject *obj)
DTrace::finalizeObject(JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED())
jsdtrace_object_finalize(obj);
finalizeObjectImpl(obj);
#endif
}
inline void
DTrace::ExecutionScope::startExecution()
/* Execution scope. */
inline
DTrace::ExecutionScope::ExecutionScope(JSScript *script)
: script(script)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_START_ENABLED())
jsdtrace_execute_start(script);
startExecution();
#endif
}
inline
DTrace::ExecutionScope::~ExecutionScope()
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
endExecution();
#endif
}
/* Object creation scope. */
inline
DTrace::ObjectCreationScope::ObjectCreationScope(JSContext *cx, JSStackFrame *fp, JSClass *clasp)
: cx(cx), fp(fp), clasp(clasp)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED())
handleCreationStart();
#endif
}
inline void
DTrace::ExecutionScope::endExecution()
DTrace::ObjectCreationScope::handleCreation(JSObject *obj)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_EXECUTE_DONE_ENABLED())
jsdtrace_execute_done(script);
if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
handleCreationImpl(obj);
#endif
}
inline
DTrace::ObjectCreationScope::~ObjectCreationScope()
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
handleCreationEnd();
#endif
}

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

@ -1882,7 +1882,7 @@ EmitEnterBlock(JSContext *cx, JSParseNode *pn, JSCodeGenerator *cg)
}
blockObj->scope()->freeslot = JSSLOT_FREE(&js_BlockClass);
return js_GrowSlots(cx, blockObj, JSSLOT_FREE(&js_BlockClass));
return blockObj->growSlots(cx, JSSLOT_FREE(&js_BlockClass));
}
/*
@ -2688,10 +2688,9 @@ static JSBool
EmitSpecialPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
{
/*
* Special case for obj.__proto__ and obj.__parent__ to deoptimize away
* from fast paths in the interpreter and trace recorder, which skip dense
* array instances by going up to Array.prototype before looking up the
* property name.
* Special case for obj.__proto__ to deoptimize away from fast paths in the
* interpreter and trace recorder, which skip dense array instances by
* going up to Array.prototype before looking up the property name.
*/
JSAtomListElement *ale = cg->atomList.add(cg->parser, pn->pn_atom);
if (!ale)
@ -2713,10 +2712,9 @@ EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg,
JS_ASSERT(pn->pn_arity == PN_NAME);
pn2 = pn->maybeExpr();
/* Special case deoptimization on __proto__ and __parent__. */
/* Special case deoptimization for __proto__. */
if ((op == JSOP_GETPROP || op == JSOP_CALLPROP) &&
(pn->pn_atom == cx->runtime->atomState.protoAtom ||
pn->pn_atom == cx->runtime->atomState.parentAtom)) {
pn->pn_atom == cx->runtime->atomState.protoAtom) {
if (pn2 && !js_EmitTree(cx, cg, pn2))
return JS_FALSE;
return EmitSpecialPropOp(cx, pn, callContext ? JSOP_CALLELEM : JSOP_GETELEM, cg);
@ -2802,13 +2800,8 @@ EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg,
return JS_FALSE;
}
/*
* Special case deoptimization on __proto__ and __parent__, as
* above.
*/
if (pndot->pn_arity == PN_NAME &&
(pndot->pn_atom == cx->runtime->atomState.protoAtom ||
pndot->pn_atom == cx->runtime->atomState.parentAtom)) {
/* Special case deoptimization on __proto__, as above. */
if (pndot->pn_arity == PN_NAME && pndot->pn_atom == cx->runtime->atomState.protoAtom) {
if (!EmitSpecialPropOp(cx, pndot, JSOP_GETELEM, cg))
return JS_FALSE;
} else if (!EmitAtomOp(cx, pndot, PN_OP(pndot), cg)) {
@ -7409,9 +7402,8 @@ js_FinishTakingTryNotes(JSCodeGenerator *cg, JSTryNoteArray *array)
*
* In such cases, naively following ECMA leads to wrongful sharing of RegExp
* objects, which makes for collisions on the lastIndex property (especially
* for global regexps) and on any ad-hoc properties. Also, __proto__ and
* __parent__ refer to the pre-compilation prototype and global objects, a
* pigeon-hole problem for instanceof tests.
* for global regexps) and on any ad-hoc properties. Also, __proto__ refers to
* the pre-compilation prototype, a pigeon-hole problem for instanceof tests.
*/
uintN
JSCGObjectList::index(JSObjectBox *objbox)

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

@ -576,9 +576,8 @@ ArgSetter(JSContext *cx, JSObject *obj, jsval idval, jsval *vp)
* args_delete to clear the corresponding reserved slot so the GC can
* collect its value.
*/
jsid id;
if (!JS_ValueToId(cx, idval, &id))
return false;
JS_ASSERT_IF(JSVAL_IS_STRING(idval), JSVAL_TO_STRING(idval)->isAtomized());
jsid id = (jsid)idval;
AutoValueRooter tvr(cx);
return js_DeleteProperty(cx, obj, id, tvr.addr()) &&
@ -1151,7 +1150,6 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
{
jsval callee;
JSFunction *fun;
jsid id;
JSLocalKind localKind;
JSPropertyOp getter, setter;
uintN slot, attrs;
@ -1162,14 +1160,14 @@ call_resolve(JSContext *cx, JSObject *obj, jsval idval, uintN flags,
if (!JSVAL_IS_STRING(idval))
return JS_TRUE;
JS_ASSERT(JSVAL_TO_STRING(idval)->isAtomized());
jsid id = (jsval)idval;
callee = obj->getSlot(JSSLOT_CALLEE);
if (JSVAL_IS_VOID(callee))
return JS_TRUE;
fun = GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(callee));
if (!js_ValueToStringId(cx, idval, &id))
return JS_FALSE;
/*
* Check whether the id refers to a formal parameter, local variable or
* the arguments special name.

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

@ -1559,6 +1559,8 @@ js_TraceOpcode(JSContext *cx)
(n == -ndefs) ? " output:" : ",",
bytes);
cx->free(bytes);
} else {
JS_ClearPendingException(cx);
}
}
fprintf(tracefp, " @ %u\n", (uintN) (regs->sp - StackBase(fp)));
@ -1566,10 +1568,12 @@ js_TraceOpcode(JSContext *cx)
fprintf(tracefp, " stack: ");
for (siter = StackBase(fp); siter < regs->sp; siter++) {
str = js_ValueToString(cx, *siter);
if (!str)
if (!str) {
fputs("<null>", tracefp);
else
} else {
JS_ClearPendingException(cx);
js_FileEscapedString(tracefp, str, 0);
}
fputc(' ', tracefp);
}
fputc('\n', tracefp);
@ -1591,6 +1595,8 @@ js_TraceOpcode(JSContext *cx)
(n == -nuses) ? " inputs:" : ",",
bytes);
cx->free(bytes);
} else {
JS_ClearPendingException(cx);
}
}
fprintf(tracefp, " @ %u\n", (uintN) (regs->sp - StackBase(fp)));

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

@ -126,59 +126,29 @@ JSClass js_ObjectClass = {
#if JS_HAS_OBJ_PROTO_PROP
static JSBool
obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
obj_getProto(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
static JSBool
obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
obj_setProto(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
static JSPropertySpec object_props[] = {
/* These two must come first; see object_props[slot].name usage below. */
{js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT|JSPROP_SHARED,
obj_getSlot, obj_setSlot},
{js_parent_str,JSSLOT_PARENT,JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED,
obj_getSlot, obj_setSlot},
{js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT|JSPROP_SHARED, obj_getProto, obj_setProto},
{0,0,0,0,0}
};
/* NB: JSSLOT_PROTO and JSSLOT_PARENT are already indexes into object_props. */
#define JSSLOT_COUNT 2
static JSBool
ReportStrictSlot(JSContext *cx, uint32 slot)
obj_getProto(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
if (slot == JSSLOT_PROTO)
return JS_TRUE;
return JS_ReportErrorFlagsAndNumber(cx,
JSREPORT_WARNING | JSREPORT_STRICT,
js_GetErrorMessage, NULL,
JSMSG_DEPRECATED_USAGE,
object_props[slot].name);
}
static JSBool
obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
jsid propid;
JSAccessMode mode;
uintN attrs;
JSObject *pobj;
JSClass *clasp;
if (id == INT_TO_JSVAL(JSSLOT_PROTO)) {
propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
mode = JSACC_PROTO;
} else {
propid = ATOM_TO_JSID(cx->runtime->atomState.parentAtom);
mode = JSACC_PARENT;
}
JS_ASSERT(id == INT_TO_JSID(JSSLOT_PROTO));
/* Let obj->checkAccess get the slot's value, based on the access mode. */
if (!obj->checkAccess(cx, propid, mode, vp, &attrs))
uintN attrs;
id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
if (!obj->checkAccess(cx, id, JSACC_PROTO, vp, &attrs))
return JS_FALSE;
pobj = JSVAL_TO_OBJECT(*vp);
if (pobj) {
clasp = pobj->getClass();
if (JSObject *pobj = JSVAL_TO_OBJECT(*vp)) {
JSClass *clasp = pobj->getClass();
if (clasp == &js_CallClass || clasp == &js_BlockClass) {
/* Censor activations and lexical scopes per ECMA-262. */
*vp = JSVAL_NULL;
@ -188,8 +158,8 @@ obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
* censor. So it cannot escape to scripts.
*/
JS_ASSERT(clasp != &js_DeclEnvClass);
if (pobj->map->ops->thisObject) {
pobj = pobj->map->ops->thisObject(cx, pobj);
if (JSObjectOp thisObject = pobj->map->ops->thisObject) {
pobj = thisObject(cx, pobj);
if (!pobj)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(pobj);
@ -200,17 +170,14 @@ obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
}
static JSBool
obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
obj_setProto(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
{
JSObject *pobj;
uint32 slot;
jsid propid;
uintN attrs;
JS_ASSERT(id == INT_TO_JSID(JSSLOT_PROTO));
if (!JSVAL_IS_OBJECT(*vp))
return JS_TRUE;
pobj = JSVAL_TO_OBJECT(*vp);
JSObject *pobj = JSVAL_TO_OBJECT(*vp);
if (pobj) {
/*
* Innerize pobj here to avoid sticking unwanted properties on the
@ -221,16 +188,13 @@ obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
if (!pobj)
return JS_FALSE;
}
slot = (uint32) JSVAL_TO_INT(id);
if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot))
uintN attrs;
id = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
if (!obj->checkAccess(cx, id, JSAccessMode(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
return JS_FALSE;
/* __parent__ is readonly and permanent, only __proto__ may be set. */
propid = ATOM_TO_JSID(cx->runtime->atomState.protoAtom);
if (!obj->checkAccess(cx, propid, (JSAccessMode)(JSACC_PROTO|JSACC_WRITE), vp, &attrs))
return JS_FALSE;
return js_SetProtoOrParent(cx, obj, slot, pobj, JS_TRUE);
return js_SetProtoOrParent(cx, obj, JSSLOT_PROTO, pobj, JS_TRUE);
}
#else /* !JS_HAS_OBJ_PROTO_PROP */
@ -300,15 +264,8 @@ js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj,
}
if (ssr.cycle) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
JSMSG_CYCLIC_VALUE,
#if JS_HAS_OBJ_PROTO_PROP
object_props[slot].name
#else
(slot == JSSLOT_PROTO) ? js_proto_str
: js_parent_str
#endif
);
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CYCLIC_VALUE,
(slot == JSSLOT_PROTO) ? js_proto_str : "parent");
return JS_FALSE;
}
}
@ -1951,13 +1908,12 @@ obj_keys(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
*vp = OBJECT_TO_JSVAL(aobj);
jsval *slots = aobj->dslots;
size_t len = ida.length();
JS_ASSERT(aobj->getDenseArrayCapacity() >= len);
for (size_t i = 0; i < len; i++) {
jsid id = ida[i];
if (JSID_IS_INT(id)) {
if (!js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), &slots[i]))
if (!js_ValueToStringId(cx, INT_JSID_TO_JSVAL(id), aobj->addressOfDenseArrayElement(i)))
return JS_FALSE;
} else {
/*
@ -1967,7 +1923,7 @@ obj_keys(JSContext *cx, uintN argc, jsval *vp)
* to by a QName, actually appears as a string jsid -- but in the
* interests of fidelity we pass object jsids through unchanged.
*/
slots[i] = ID_TO_VALUE(id);
aobj->setDenseArrayElement(i, ID_TO_VALUE(id));
}
}
@ -3137,7 +3093,7 @@ js_PutBlockObject(JSContext *cx, JSBool normalUnwind)
if (normalUnwind && count > 1) {
--count;
JS_LOCK_OBJ(cx, obj);
if (!js_AllocSlots(cx, obj, JS_INITIAL_NSLOTS + count))
if (!obj->allocSlots(cx, JS_INITIAL_NSLOTS + count))
normalUnwind = JS_FALSE;
else
memcpy(obj->dslots, fp->slots + depth + 1, count * sizeof(jsval));
@ -3521,35 +3477,28 @@ bad:
goto out;
}
#define SLOTS_TO_DYNAMIC_WORDS(nslots) \
(JS_ASSERT((nslots) > JS_INITIAL_NSLOTS), (nslots) + 1 - JS_INITIAL_NSLOTS)
#define DYNAMIC_WORDS_TO_SLOTS(words) \
(JS_ASSERT((words) > 1), (words) - 1 + JS_INITIAL_NSLOTS)
bool
js_AllocSlots(JSContext *cx, JSObject *obj, size_t nslots)
JSObject::allocSlots(JSContext *cx, size_t nslots)
{
JS_ASSERT(!obj->dslots);
JS_ASSERT(!dslots);
JS_ASSERT(nslots > JS_INITIAL_NSLOTS);
jsval* slots;
slots = (jsval*) cx->malloc(SLOTS_TO_DYNAMIC_WORDS(nslots) * sizeof(jsval));
if (!slots)
size_t nwords = slotsToDynamicWords(nslots);
dslots = (jsval*) cx->malloc(nwords * sizeof(jsval));
if (!dslots)
return false;
*slots++ = nslots;
dslots++;
dslots[-1] = nslots;
/* clear the newly allocated cells. */
for (jsuint n = JS_INITIAL_NSLOTS; n < nslots; ++n)
slots[n - JS_INITIAL_NSLOTS] = JSVAL_VOID;
obj->dslots = slots;
for (jsuint i = JS_INITIAL_NSLOTS; i < nslots; i++)
dslots[i - JS_INITIAL_NSLOTS] = JSVAL_VOID;
return true;
}
bool
js_GrowSlots(JSContext *cx, JSObject *obj, size_t nslots)
JSObject::growSlots(JSContext *cx, size_t nslots)
{
/*
* Minimal number of dynamic slots to allocate.
@ -3566,7 +3515,7 @@ js_GrowSlots(JSContext *cx, JSObject *obj, size_t nslots)
if (nslots <= JS_INITIAL_NSLOTS)
return JS_TRUE;
size_t nwords = SLOTS_TO_DYNAMIC_WORDS(nslots);
size_t nwords = slotsToDynamicWords(nslots);
/*
* Round up nslots so the number of bytes in dslots array is power
@ -3581,55 +3530,55 @@ js_GrowSlots(JSContext *cx, JSObject *obj, size_t nslots)
} else {
nwords = JS_ROUNDUP(nwords, LINEAR_GROWTH_STEP);
}
nslots = DYNAMIC_WORDS_TO_SLOTS(nwords);
nslots = dynamicWordsToSlots(nwords);
/*
* If nothing was allocated yet, treat it as initial allocation (but with
* the exponential growth algorithm applied).
*/
jsval* slots = obj->dslots;
if (!slots)
return js_AllocSlots(cx, obj, nslots);
if (!dslots)
return allocSlots(cx, nslots);
size_t oslots = size_t(slots[-1]);
size_t oldnslots = size_t(dslots[-1]);
slots = (jsval*) cx->realloc(slots - 1, nwords * sizeof(jsval));
if (!slots)
return false;
jsval *tmpdslots = (jsval*) cx->realloc(dslots - 1, nwords * sizeof(jsval));
if (!tmpdslots)
return false; /* Leave dslots at its old size. */
dslots = tmpdslots;
*slots++ = nslots;
obj->dslots = slots;
dslots++;
dslots[-1] = nslots;
/* Initialize the additional slots we added. */
JS_ASSERT(nslots > oslots);
for (size_t i = oslots; i < nslots; i++)
slots[i - JS_INITIAL_NSLOTS] = JSVAL_VOID;
JS_ASSERT(nslots > oldnslots);
for (size_t i = oldnslots; i < nslots; i++)
dslots[i - JS_INITIAL_NSLOTS] = JSVAL_VOID;
return true;
}
void
js_ShrinkSlots(JSContext *cx, JSObject *obj, size_t nslots)
JSObject::shrinkSlots(JSContext *cx, size_t nslots)
{
jsval* slots = obj->dslots;
/* Nothing to shrink? */
if (!slots)
if (!dslots)
return;
JS_ASSERT(size_t(slots[-1]) > JS_INITIAL_NSLOTS);
JS_ASSERT(nslots <= size_t(slots[-1]));
JS_ASSERT(size_t(dslots[-1]) > JS_INITIAL_NSLOTS);
JS_ASSERT(nslots <= size_t(dslots[-1]));
if (nslots <= JS_INITIAL_NSLOTS) {
obj->freeSlotsArray(cx);
obj->dslots = NULL;
freeSlotsArray(cx);
dslots = NULL;
} else {
size_t nwords = SLOTS_TO_DYNAMIC_WORDS(nslots);
slots = (jsval*) cx->realloc(slots - 1, nwords * sizeof(jsval));
if (!slots)
return; /* Leave obj->dslots at its old size. */
*slots++ = nslots;
obj->dslots = slots;
size_t nwords = slotsToDynamicWords(nslots);
jsval *tmpdslots = (jsval*) cx->realloc(dslots - 1, nwords * sizeof(jsval));
if (!tmpdslots)
return; /* Leave dslots at its old size. */
dslots = tmpdslots;
dslots++;
dslots[-1] = nslots;
}
}
@ -3637,10 +3586,9 @@ bool
js_EnsureReservedSlots(JSContext *cx, JSObject *obj, size_t nreserved)
{
JS_ASSERT(obj->isNative());
JS_ASSERT(!obj->dslots);
uintN nslots = JSSLOT_FREE(obj->getClass()) + nreserved;
if (nslots > obj->numSlots() && !js_AllocSlots(cx, obj, nslots))
if (nslots > obj->numSlots() && !obj->allocSlots(cx, nslots))
return false;
JSScope *scope = obj->scope();
@ -3839,8 +3787,8 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
AutoValueRooter tvr(cx, cval);
/*
* If proto or parent are NULL, set them to Constructor.prototype and/or
* Constructor.__parent__, just like JSOP_NEW does.
* If proto is NULL, set it to Constructor.prototype, just like JSOP_NEW
* does, likewise for the new object's parent.
*/
ctor = JSVAL_TO_OBJECT(cval);
if (!parent)
@ -3900,7 +3848,7 @@ js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp)
}
if (scope->freeslot >= obj->numSlots() &&
!js_GrowSlots(cx, obj, scope->freeslot + 1)) {
!obj->growSlots(cx, scope->freeslot + 1)) {
return JS_FALSE;
}
@ -5691,10 +5639,10 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
* We don't want to require all classes to supply a checkAccess hook; we
* need that hook only for certain classes used when precompiling scripts
* and functions ("brutal sharing"). But for general safety of built-in
* magic properties such as __proto__ and __parent__, we route all access
* checks, even for classes that stub out checkAccess, through the global
* checkObjectAccess hook. This covers precompilation-based sharing and
* (possibly unintended) runtime sharing across trust boundaries.
* magic properties like __proto__, we route all access checks, even for
* classes that stub out checkAccess, through the global checkObjectAccess
* hook. This covers precompilation-based sharing and (possibly
* unintended) runtime sharing across trust boundaries.
*/
clasp = pobj->getClass();
check = clasp->checkAccess;
@ -6304,7 +6252,7 @@ js_TraceObject(JSTracer *trc, JSObject *obj)
*/
size_t slots = scope->freeslot;
if (obj->numSlots() != slots)
js_ShrinkSlots(cx, obj, slots);
obj->shrinkSlots(cx, slots);
}
#ifdef JS_DUMP_SCOPE_METERS
@ -6432,17 +6380,17 @@ js_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v)
#endif
uint32 slot = JSSLOT_START(clasp) + index;
if (slot >= JS_INITIAL_NSLOTS && !obj->dslots) {
if (slot >= obj->numSlots()) {
/*
* At this point, obj may or may not own scope, and we may or may not
* need to allocate dslots. If scope is shared, scope->freeslot may not
* need to allocate slots. If scope is shared, scope->freeslot may not
* be accurate for obj (see comment below).
*/
uint32 nslots = JSSLOT_FREE(clasp);
if (clasp->reserveSlots)
nslots += clasp->reserveSlots(cx, obj);
JS_ASSERT(slot < nslots);
if (!js_AllocSlots(cx, obj, nslots)) {
if (!obj->allocSlots(cx, nslots)) {
JS_UNLOCK_OBJ(cx, obj);
return false;
}

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

@ -296,6 +296,22 @@ struct JSObject {
return dslots ? (uint32)dslots[-1] : (uint32)JS_INITIAL_NSLOTS;
}
private:
static size_t slotsToDynamicWords(size_t nslots) {
JS_ASSERT(nslots > JS_INITIAL_NSLOTS);
return nslots + 1 - JS_INITIAL_NSLOTS;
}
static size_t dynamicWordsToSlots(size_t nwords) {
JS_ASSERT(nwords > 1);
return nwords - 1 + JS_INITIAL_NSLOTS;
}
public:
bool allocSlots(JSContext *cx, size_t nslots);
bool growSlots(JSContext *cx, size_t nslots);
void shrinkSlots(JSContext *cx, size_t nslots);
jsval& getSlotRef(uintN slot) {
return (slot < JS_INITIAL_NSLOTS)
? fslots[slot]
@ -364,7 +380,7 @@ struct JSObject {
JSObject *parent = getParent();
if (parent)
JS_CALL_OBJECT_TRACER(trc, parent, "__parent__");
JS_CALL_OBJECT_TRACER(trc, parent, "parent");
}
JSObject *getGlobal();
@ -417,8 +433,6 @@ struct JSObject {
// The static assertion isn't inline because that doesn't work on Mac.)
inline void staticAssertArrayLengthIsInPrivateSlot();
inline bool isDenseArrayMinLenCapOk() const;
inline uint32 uncheckedGetArrayLength() const;
inline uint32 uncheckedGetDenseArrayCapacity() const;
@ -435,7 +449,10 @@ struct JSObject {
inline uint32 getDenseArrayCapacity() const;
inline void setDenseArrayCapacity(uint32 capacity); // XXX: bug 558263 will remove this
inline bool isDenseArrayMinLenCapOk(bool strictAboutLength = true) const;
inline jsval getDenseArrayElement(uint32 i) const;
inline jsval *addressOfDenseArrayElement(uint32 i);
inline void setDenseArrayElement(uint32 i, jsval v);
inline jsval *getDenseArrayElements() const; // returns pointer to the Array's elements array
@ -872,15 +889,6 @@ js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp);
extern void
js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot);
extern bool
js_AllocSlots(JSContext *cx, JSObject *obj, size_t nslots);
extern bool
js_GrowSlots(JSContext *cx, JSObject *obj, size_t nslots);
extern void
js_ShrinkSlots(JSContext *cx, JSObject *obj, size_t nslots);
/*
* Ensure that the object has at least JSCLASS_RESERVED_SLOTS(clasp)+nreserved
* slots. The function can be called only for native objects just created with

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

@ -46,10 +46,7 @@
#include "jsiter.h"
#include "jsobj.h"
#include "jsscope.h"
#ifdef INCLUDE_MOZILLA_DTRACE
#include "jsdtracef.h"
#endif
#include "jsscopeinlines.h"
@ -110,18 +107,26 @@ JSObject::setPrimitiveThis(jsval pthis)
fslots[JSSLOT_PRIMITIVE_THIS] = pthis;
}
inline void JSObject::staticAssertArrayLengthIsInPrivateSlot()
inline void
JSObject::staticAssertArrayLengthIsInPrivateSlot()
{
JS_STATIC_ASSERT(JSSLOT_ARRAY_LENGTH == JSSLOT_PRIVATE);
}
inline bool JSObject::isDenseArrayMinLenCapOk() const
inline bool
JSObject::isDenseArrayMinLenCapOk(bool strictAboutLength) const
{
JS_ASSERT(isDenseArray());
uint32 length = uncheckedGetArrayLength();
uint32 capacity = uncheckedGetDenseArrayCapacity();
uint32 minLenCap = uint32(fslots[JSSLOT_DENSE_ARRAY_MINLENCAP]);
return minLenCap == JS_MIN(length, capacity);
// This function can be called while the LENGTH and MINLENCAP slots are
// still set to JSVAL_VOID and there are no dslots (ie. the capacity is
// zero). If 'strictAboutLength' is false we allow this.
return minLenCap == JS_MIN(length, capacity) ||
(!strictAboutLength && minLenCap == uint32(JSVAL_VOID) &&
length == uint32(JSVAL_VOID) && capacity == 0);
}
inline uint32
@ -192,7 +197,7 @@ inline uint32
JSObject::getDenseArrayCapacity() const
{
JS_ASSERT(isDenseArray());
JS_ASSERT(isDenseArrayMinLenCapOk());
JS_ASSERT(isDenseArrayMinLenCapOk(/* strictAboutLength = */false));
return uncheckedGetDenseArrayCapacity();
}
@ -214,6 +219,14 @@ JSObject::getDenseArrayElement(uint32 i) const
return dslots[i];
}
inline jsval *
JSObject::addressOfDenseArrayElement(uint32 i)
{
JS_ASSERT(isDenseArray());
JS_ASSERT(i < getDenseArrayCapacity());
return &dslots[i];
}
inline void
JSObject::setDenseArrayElement(uint32 i, jsval v)
{
@ -477,7 +490,7 @@ InitScopeForObject(JSContext* cx, JSObject* obj, JSClass *clasp, JSObject* proto
/* Let JSScope::create set freeslot so as to reserve slots. */
JS_ASSERT(scope->freeslot >= JSSLOT_PRIVATE);
if (scope->freeslot > JS_INITIAL_NSLOTS &&
!js_AllocSlots(cx, obj, scope->freeslot)) {
!obj->allocSlots(cx, scope->freeslot)) {
scope->destroy(cx);
goto bad;
}
@ -496,10 +509,7 @@ static inline JSObject *
NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
JSObject *parent, size_t objectSize = 0)
{
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED())
jsdtrace_object_create_start(cx->fp, clasp);
#endif
DTrace::ObjectCreationScope objectCreationScope(cx, cx->fp, clasp);
/* Assert that the class is a proper class. */
JS_ASSERT_IF(clasp->flags & JSCLASS_IS_EXTENDED,
@ -565,12 +575,7 @@ NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
}
out:
#ifdef INCLUDE_MOZILLA_DTRACE
if (JAVASCRIPT_OBJECT_CREATE_ENABLED())
jsdtrace_object_create(cx, clasp, obj);
if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED())
jsdtrace_object_create_done(cx->fp, clasp);
#endif
objectCreationScope.handleCreation(obj);
return obj;
}

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

@ -3274,6 +3274,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
cond -= tail;
DECOMPILE_CODE(pc + oplen, cond - oplen);
pc += cond;
oplen = js_CodeSpec[*pc].length;
elseif = JS_TRUE;
goto if_again;
}

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

@ -3333,9 +3333,8 @@ BEGIN_CASE(JSOP_INITMETHOD)
* So check first.
*
* On a hit, if the cached sprop has a non-default setter, it must be
* __proto__ or __parent__. If sprop->parent != scope->lastProperty(),
* there is a repeated property name. The fast path does not handle these
* two cases.
* __proto__. If sprop->parent != scope->lastProperty(), there is a
* repeated property name. The fast path does not handle these two cases.
*/
if (CX_OWNS_OBJECT_TITLE(cx, obj) &&
JS_PROPERTY_CACHE(cx).testForInit(rt, regs.pc, obj, scope, &sprop, &entry) &&

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

@ -3198,7 +3198,7 @@ BindLet(JSContext *cx, BindData *data, JSAtom *atom, JSTreeContext *tc)
*/
uintN slot = JSSLOT_FREE(&js_BlockClass) + n;
if (slot >= blockObj->numSlots() &&
!js_GrowSlots(cx, blockObj, slot + 1)) {
!blockObj->growSlots(cx, slot + 1)) {
return JS_FALSE;
}
blockObj->scope()->freeslot = slot + 1;
@ -6274,6 +6274,7 @@ Parser::unaryExpr()
break;
case TOK_DELETE:
{
pn = UnaryNode::create(tc);
if (!pn)
return NULL;
@ -6301,12 +6302,14 @@ Parser::unaryExpr()
JSMSG_DEPRECATED_DELETE_OPERAND))
return NULL;
pn2->pn_op = JSOP_DELNAME;
if (pn2->pn_atom == context->runtime->atomState.argumentsAtom)
tc->flags |= TCF_FUN_HEAVYWEIGHT;
break;
default:;
}
pn->pn_kid = pn2;
break;
}
case TOK_ERROR:
return NULL;

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

@ -55,7 +55,7 @@ class RecursiveSlotMap : public SlotMap
{
/* Check if the return value should be promoted. */
if (slots[downPostSlots].lastCheck == TypeCheck_Demote)
rval_ins = mRecorder.lir->ins1(LIR_i2f, rval_ins);
rval_ins = mRecorder.lir->ins1(LIR_i2d, rval_ins);
/* Adjust any global variables. */
for (unsigned i = downPostSlots + 1; i < slots.length(); i++)
adjustType(slots[i]);
@ -111,10 +111,10 @@ class UpRecursiveSlotMap : public RecursiveSlotMap
*/
lir->insStore(rval_ins, lirbuf->sp, -mRecorder.tree->nativeStackBase, ACC_STACK);
lirbuf->sp = lir->ins2(LIR_piadd, lirbuf->sp,
lirbuf->sp = lir->ins2(LIR_addp, lirbuf->sp,
lir->insImmWord(-int(downPostSlots) * sizeof(double)));
lir->insStore(lirbuf->sp, lirbuf->state, offsetof(TracerState, sp), ACC_OTHER);
lirbuf->rp = lir->ins2(LIR_piadd, lirbuf->rp,
lirbuf->rp = lir->ins2(LIR_addp, lirbuf->rp,
lir->insImmWord(-int(sizeof(FrameInfo*))));
lir->insStore(lirbuf->rp, lirbuf->state, offsetof(TracerState, rp), ACC_OTHER);
}
@ -286,8 +286,8 @@ TraceRecorder::upRecursion()
/* Guard that rp >= sr + 1 */
guard(true,
lir->ins2(LIR_pge, lirbuf->rp,
lir->ins2(LIR_piadd,
lir->ins2(LIR_gep, lirbuf->rp,
lir->ins2(LIR_addp,
lir->insLoad(LIR_ldp, lirbuf->state,
offsetof(TracerState, sor), ACC_OTHER),
INS_CONSTWORD(sizeof(FrameInfo*)))),
@ -299,7 +299,7 @@ TraceRecorder::upRecursion()
/* Guard that the FrameInfo above is the same FrameInfo pointer. */
VMSideExit* exit = snapshot(RECURSIVE_MISMATCH_EXIT);
LIns* prev_rp = lir->insLoad(LIR_ldp, lirbuf->rp, -int32_t(sizeof(FrameInfo*)), ACC_RSTACK);
guard(true, lir->ins2(LIR_peq, prev_rp, INS_CONSTPTR(fi)), exit);
guard(true, lir->ins2(LIR_eqp, prev_rp, INS_CONSTPTR(fi)), exit);
/*
* Now it's time to try and close the loop. Get a special exit that points
@ -419,7 +419,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
* end-of-recursion and recursion-returns-to-different-pc.
*/
guard(true,
lir->ins2(LIR_peq,
lir->ins2(LIR_eqp,
addName(lir->insLoad(LIR_ldp, fp_ins,
offsetof(JSStackFrame, script), ACC_OTHER),
"script"),
@ -429,7 +429,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
/* fp->down->regs->pc should be == pc. */
guard(true,
lir->ins2(LIR_peq,
lir->ins2(LIR_eqp,
lir->insLoad(LIR_ldp,
addName(lir->insLoad(LIR_ldp, fp_ins,
offsetof(JSStackFrame, regs), ACC_OTHER),
@ -440,8 +440,8 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
/* fp->down->argc should be == argc. */
guard(true,
lir->ins2(LIR_eq,
addName(lir->insLoad(LIR_ld, fp_ins, offsetof(JSStackFrame, argc),
lir->ins2(LIR_eqi,
addName(lir->insLoad(LIR_ldi, fp_ins, offsetof(JSStackFrame, argc),
ACC_OTHER),
"argc"),
INS_CONST(cx->fp->argc)),
@ -550,10 +550,10 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
case TT_SPECIAL:
case TT_VOID:
case TT_INT32:
rval_ins = lir->insLoad(LIR_ld, lirbuf->sp, offset, ACC_STACK);
rval_ins = lir->insLoad(LIR_ldi, lirbuf->sp, offset, ACC_STACK);
break;
case TT_DOUBLE:
rval_ins = lir->insLoad(LIR_ldf, lirbuf->sp, offset, ACC_STACK);
rval_ins = lir->insLoad(LIR_ldd, lirbuf->sp, offset, ACC_STACK);
break;
case TT_FUNCTION:
case TT_OBJECT:
@ -609,7 +609,7 @@ TraceRecorder::slurpDownFrames(jsbytecode* return_pc)
/* stack vals */
unsigned nfixed = fp->script->nfixed;
jsval* stack = StackBase(fp);
LIns* stack_ins = addName(lir->ins2(LIR_piadd,
LIns* stack_ins = addName(lir->ins2(LIR_addp,
slots_ins,
INS_CONSTWORD(nfixed * sizeof(jsval))),
"stackBase");
@ -684,12 +684,12 @@ TraceRecorder::downRecursion()
JS_ASSERT(tree->maxNativeStackSlots >= tree->nativeStackBase / sizeof(double));
int guardSlots = slots + tree->maxNativeStackSlots -
tree->nativeStackBase / sizeof(double);
LIns* sp_top = lir->ins2(LIR_piadd, lirbuf->sp, lir->insImmWord(guardSlots * sizeof(double)));
guard(true, lir->ins2(LIR_plt, sp_top, eos_ins), OOM_EXIT);
LIns* sp_top = lir->ins2(LIR_addp, lirbuf->sp, lir->insImmWord(guardSlots * sizeof(double)));
guard(true, lir->ins2(LIR_ltp, sp_top, eos_ins), OOM_EXIT);
/* Guard that there is enough call stack space. */
LIns* rp_top = lir->ins2(LIR_piadd, lirbuf->rp, lir->insImmWord(sizeof(FrameInfo*)));
guard(true, lir->ins2(LIR_plt, rp_top, eor_ins), OOM_EXIT);
LIns* rp_top = lir->ins2(LIR_addp, lirbuf->rp, lir->insImmWord(sizeof(FrameInfo*)));
guard(true, lir->ins2(LIR_ltp, rp_top, eor_ins), OOM_EXIT);
/*
* For every slot in the new frame that is not in the tracker, create a load
@ -702,9 +702,9 @@ TraceRecorder::downRecursion()
VisitStackSlots(visitor, cx, callDepth);
/* Add space for a new JIT frame. */
lirbuf->sp = lir->ins2(LIR_piadd, lirbuf->sp, lir->insImmWord(slots * sizeof(double)));
lirbuf->sp = lir->ins2(LIR_addp, lirbuf->sp, lir->insImmWord(slots * sizeof(double)));
lir->insStore(lirbuf->sp, lirbuf->state, offsetof(TracerState, sp), ACC_OTHER);
lirbuf->rp = lir->ins2(LIR_piadd, lirbuf->rp, lir->insImmWord(sizeof(FrameInfo*)));
lirbuf->rp = lir->ins2(LIR_addp, lirbuf->rp, lir->insImmWord(sizeof(FrameInfo*)));
lir->insStore(lirbuf->rp, lirbuf->state, offsetof(TracerState, rp), ACC_OTHER);
--callDepth;
clearCurrentFrameSlotsFromTracker(nativeFrameTracker);
@ -734,19 +734,19 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::slurpInt32Slot(LIns* val_ins, jsval* vp, VMSideExit* exit)
{
guard(true,
lir->ins2(LIR_or,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
lir->ins2(LIR_ori,
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
INS_CONSTWORD(JSVAL_DOUBLE)),
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(1)),
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(1)),
INS_CONSTWORD(1))),
exit);
LIns* space = lir->insAlloc(sizeof(int32));
LIns* args[] = { space, val_ins };
LIns* result = lir->insCall(&js_TryUnboxInt32_ci, args);
guard(false, lir->insEqI_0(result), exit);
LIns* int32_ins = lir->insLoad(LIR_ld, space, 0, ACC_OTHER);
LIns* int32_ins = lir->insLoad(LIR_ldi, space, 0, ACC_OTHER);
return int32_ins;
}
@ -754,12 +754,12 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::slurpDoubleSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
{
guard(true,
lir->ins2(LIR_or,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
lir->ins2(LIR_ori,
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
INS_CONSTWORD(JSVAL_DOUBLE)),
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(1)),
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(1)),
INS_CONSTWORD(1))),
exit);
LIns* args[] = { val_ins };
@ -771,11 +771,11 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::slurpSpecialSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
{
guard(true,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
INS_CONSTWORD(JSVAL_SPECIAL)),
exit);
LIns* bool_ins = lir->ins2(LIR_pirsh, val_ins, INS_CONST(JSVAL_TAGBITS));
LIns* bool_ins = lir->ins2(LIR_rshp, val_ins, INS_CONST(JSVAL_TAGBITS));
bool_ins = p2i(bool_ins);
return bool_ins;
}
@ -783,7 +783,7 @@ TraceRecorder::slurpSpecialSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
JS_REQUIRES_STACK LIns*
TraceRecorder::slurpVoidSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
{
guard(true, lir->ins2(LIR_peq, val_ins, INS_CONSTWORD(JSVAL_VOID)), exit);
guard(true, lir->ins2(LIR_eqp, val_ins, INS_CONSTWORD(JSVAL_VOID)), exit);
return INS_VOID();
}
@ -791,11 +791,11 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::slurpStringSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
{
guard(true,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK)),
INS_CONSTWORD(JSVAL_STRING)),
exit);
LIns* str_ins = lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(~JSVAL_TAGMASK));
LIns* str_ins = lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(~JSVAL_TAGMASK));
return str_ins;
}
@ -814,13 +814,13 @@ TraceRecorder::slurpObjectSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
/* Must be an object */
guard(true,
lir->insEqP_0(lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK))),
lir->insEqP_0(lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK))),
exit);
/* Must NOT have a function class */
guard(false,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand,
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp,
lir->insLoad(LIR_ldp, val_ins, offsetof(JSObject, classword),
ACC_OTHER),
INS_CONSTWORD(~JSSLOT_CLASS_MASK_BITS)),
@ -837,13 +837,13 @@ TraceRecorder::slurpFunctionSlot(LIns* val_ins, jsval* vp, VMSideExit* exit)
/* Must be an object */
guard(true,
lir->insEqP_0(lir->ins2(LIR_piand, val_ins, INS_CONSTWORD(JSVAL_TAGMASK))),
lir->insEqP_0(lir->ins2(LIR_andp, val_ins, INS_CONSTWORD(JSVAL_TAGMASK))),
exit);
/* Must have a function class */
guard(true,
lir->ins2(LIR_peq,
lir->ins2(LIR_piand,
lir->ins2(LIR_eqp,
lir->ins2(LIR_andp,
lir->insLoad(LIR_ldp, val_ins, offsetof(JSObject, classword),
ACC_OTHER),
INS_CONSTWORD(~JSSLOT_CLASS_MASK_BITS)),

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

@ -2382,10 +2382,10 @@ class RegExpNativeCompiler {
LIns* compileFlatSingleChar(jschar ch, LIns* pos, LInsList& fails)
{
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_plt, pos, cpend), 0);
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_ltp, pos, cpend), 0);
if (!fails.append(to_fail))
return NULL;
LIns* text_ch = lir->insLoad(LIR_ldzs, pos, 0, ACC_READONLY);
LIns* text_ch = lir->insLoad(LIR_ldus2ui, pos, 0, ACC_READONLY);
// Extra characters that need to be compared against when doing folding.
struct extra {
@ -2402,7 +2402,7 @@ class RegExpNativeCompiler {
if (ch != lch) {
if (L'A' <= ch && ch <= L'Z') {
// Fast conversion of text character to lower case by OR-ing with 32.
text_ch = lir->ins2(LIR_or, text_ch, lir->insImmI(32));
text_ch = lir->ins2(LIR_ori, text_ch, lir->insImmI(32));
// These ASCII letters have 2 lower-case forms. We put the ASCII one in
// |extras| so it is tested first, because we expect that to be the common
// case. Note that the code points of the non-ASCII forms both have the
@ -2464,17 +2464,17 @@ class RegExpNativeCompiler {
gen:
for (int i = 0; i < nextras; ++i) {
LIns *test = lir->ins2(LIR_eq, text_ch, lir->insImmI(extras[i].ch));
LIns *test = lir->ins2(LIR_eqi, text_ch, lir->insImmI(extras[i].ch));
LIns *branch = lir->insBranch(LIR_jt, test, 0);
extras[i].match = branch;
}
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_eq, text_ch, lir->insImmI(ch)), 0)))
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_eqi, text_ch, lir->insImmI(ch)), 0)))
return NULL;
for (int i = 0; i < nextras; ++i)
targetCurrentPoint(extras[i].match);
return lir->ins2(LIR_piadd, pos, lir->insImmWord(2));
return lir->ins2(LIR_addp, pos, lir->insImmWord(2));
}
JS_INLINE bool hasCases(jschar ch)
@ -2516,22 +2516,22 @@ class RegExpNativeCompiler {
}
LIns* to_fail = lir->insBranch(LIR_jf,
lir->ins2(LIR_plt,
lir->ins2(LIR_ltp,
pos,
lir->ins2(LIR_piadd,
lir->ins2(LIR_addp,
cpend,
lir->insImmWord(-2))),
0);
if (!fails.append(to_fail))
return NULL;
LIns* text_word = lir->insLoad(LIR_ld, pos, 0, ACC_OTHER);
LIns* text_word = lir->insLoad(LIR_ldi, pos, 0, ACC_OTHER);
LIns* comp_word = useFastCI ?
lir->ins2(LIR_or, text_word, lir->insImmI(mask.i)) :
lir->ins2(LIR_ori, text_word, lir->insImmI(mask.i)) :
text_word;
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_eq, comp_word, lir->insImmI(word)), 0)))
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_eqi, comp_word, lir->insImmI(word)), 0)))
return NULL;
return lir->ins2(LIR_piadd, pos, lir->insImmWord(4));
return lir->ins2(LIR_addp, pos, lir->insImmWord(4));
}
LIns* compileFlat(RENode *&node, LIns* pos, LInsList& fails)
@ -2603,27 +2603,27 @@ class RegExpNativeCompiler {
return NULL;
memcpy(bitmapData, charSet->u.bits, bitmapLen);
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_plt, pos, cpend), 0);
LIns* to_fail = lir->insBranch(LIR_jf, lir->ins2(LIR_ltp, pos, cpend), 0);
if (!fails.append(to_fail))
return NULL;
LIns* text_ch = lir->insLoad(LIR_ldzs, pos, 0, ACC_READONLY);
LIns* text_ch = lir->insLoad(LIR_ldus2ui, pos, 0, ACC_READONLY);
if (!fails.append(lir->insBranch(LIR_jf,
lir->ins2(LIR_le, text_ch, lir->insImmI(charSet->length)),
lir->ins2(LIR_lei, text_ch, lir->insImmI(charSet->length)),
0))) {
return NULL;
}
LIns* byteIndex = lir->insI2P(lir->ins2(LIR_rsh, text_ch, lir->insImmI(3)));
LIns* byteIndex = lir->insI2P(lir->ins2(LIR_rshi, text_ch, lir->insImmI(3)));
LIns* bitmap = lir->insImmP(bitmapData);
LIns* byte = lir->insLoad(LIR_ldzb, lir->ins2(LIR_piadd, bitmap, byteIndex), (int) 0,
LIns* byte = lir->insLoad(LIR_lduc2ui, lir->ins2(LIR_addp, bitmap, byteIndex), (int) 0,
ACC_READONLY);
LIns* bitMask = lir->ins2(LIR_lsh, lir->insImmI(1),
lir->ins2(LIR_and, text_ch, lir->insImmI(0x7)));
LIns* test = lir->ins2(LIR_eq, lir->ins2(LIR_and, byte, bitMask), lir->insImmI(0));
LIns* bitMask = lir->ins2(LIR_lshi, lir->insImmI(1),
lir->ins2(LIR_andi, text_ch, lir->insImmI(0x7)));
LIns* test = lir->ins2(LIR_eqi, lir->ins2(LIR_andi, byte, bitMask), lir->insImmI(0));
LIns* to_next = lir->insBranch(LIR_jt, test, 0);
if (!fails.append(to_next))
return NULL;
return lir->ins2(LIR_piadd, pos, lir->insImmWord(2));
return lir->ins2(LIR_addp, pos, lir->insImmWord(2));
}
/* Factor out common code to index js_alnum. */
@ -2631,44 +2631,44 @@ class RegExpNativeCompiler {
{
if (sizeof(bool) != 1) {
LIns *sizeLog2 = lir->insImmI(StaticLog2<sizeof(bool)>::result);
chr = lir->ins2(LIR_lsh, chr, sizeLog2);
chr = lir->ins2(LIR_lshi, chr, sizeLog2);
}
LIns *addr = lir->ins2(LIR_piadd, lir->insImmP(tbl), lir->insUI2P(chr));
return lir->insLoad(LIR_ldzb, addr, 0, ACC_READONLY);
LIns *addr = lir->ins2(LIR_addp, lir->insImmP(tbl), lir->insUI2P(chr));
return lir->insLoad(LIR_lduc2ui, addr, 0, ACC_READONLY);
}
/* Compile a builtin character class. */
LIns *compileBuiltinClass(RENode *node, LIns *pos, LInsList &fails)
{
/* All the builtins checked below consume one character. */
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_plt, pos, cpend), 0)))
if (!fails.append(lir->insBranch(LIR_jf, lir->ins2(LIR_ltp, pos, cpend), 0)))
return NULL;
LIns *chr = lir->insLoad(LIR_ldzs, pos, 0, ACC_READONLY);
LIns *chr = lir->insLoad(LIR_ldus2ui, pos, 0, ACC_READONLY);
switch (node->op) {
case REOP_DOT:
{
/* Accept any character except those in ECMA-262 15.10.2.8. */
LIns *eq1 = lir->ins2(LIR_eq, chr, lir->insImmI('\n'));
LIns *eq1 = lir->ins2(LIR_eqi, chr, lir->insImmI('\n'));
if (!fails.append(lir->insBranch(LIR_jt, eq1, NULL)))
return NULL;
LIns *eq2 = lir->ins2(LIR_eq, chr, lir->insImmI('\r'));
LIns *eq2 = lir->ins2(LIR_eqi, chr, lir->insImmI('\r'));
if (!fails.append(lir->insBranch(LIR_jt, eq2, NULL)))
return NULL;
LIns *eq3 = lir->ins2(LIR_eq, chr, lir->insImmI(LINE_SEPARATOR));
LIns *eq3 = lir->ins2(LIR_eqi, chr, lir->insImmI(LINE_SEPARATOR));
if (!fails.append(lir->insBranch(LIR_jt, eq3, NULL)))
return NULL;
LIns *eq4 = lir->ins2(LIR_eq, chr, lir->insImmI(PARA_SEPARATOR));
LIns *eq4 = lir->ins2(LIR_eqi, chr, lir->insImmI(PARA_SEPARATOR));
if (!fails.append(lir->insBranch(LIR_jt, eq4, NULL)))
return NULL;
break;
}
case REOP_DIGIT:
{
LIns *ge = lir->ins2(LIR_ge, chr, lir->insImmI('0'));
LIns *ge = lir->ins2(LIR_gei, chr, lir->insImmI('0'));
if (!fails.append(lir->insBranch(LIR_jf, ge, NULL)))
return NULL;
LIns *le = lir->ins2(LIR_le, chr, lir->insImmI('9'));
LIns *le = lir->ins2(LIR_lei, chr, lir->insImmI('9'));
if (!fails.append(lir->insBranch(LIR_jf, le, NULL)))
return NULL;
break;
@ -2676,9 +2676,9 @@ class RegExpNativeCompiler {
case REOP_NONDIGIT:
{
/* Use 'and' to give a predictable branch for success path. */
LIns *ge = lir->ins2(LIR_ge, chr, lir->insImmI('0'));
LIns *le = lir->ins2(LIR_le, chr, lir->insImmI('9'));
LIns *both = lir->ins2(LIR_and, ge, le);
LIns *ge = lir->ins2(LIR_gei, chr, lir->insImmI('0'));
LIns *le = lir->ins2(LIR_lei, chr, lir->insImmI('9'));
LIns *both = lir->ins2(LIR_andi, ge, le);
if (!fails.append(lir->insBranch(LIR_jf, lir->insEqI_0(both), NULL)))
return NULL;
break;
@ -2689,7 +2689,7 @@ class RegExpNativeCompiler {
* Compile the condition:
* ((uint)*cp) < 128 && js_alnum[(uint)*cp]
*/
LIns *rangeCnd = lir->ins2(LIR_ult, chr, lir->insImmI(128));
LIns *rangeCnd = lir->ins2(LIR_ltui, chr, lir->insImmI(128));
if (!fails.append(lir->insBranch(LIR_jf, rangeCnd, NULL)))
return NULL;
LIns *tableVal = compileTableRead(chr, js_alnum);
@ -2703,7 +2703,7 @@ class RegExpNativeCompiler {
* Compile the condition:
* ((uint)*cp) >= 128 || !js_alnum[(uint)*cp]
*/
LIns *rangeCnd = lir->ins2(LIR_uge, chr, lir->insImmI(128));
LIns *rangeCnd = lir->ins2(LIR_geui, chr, lir->insImmI(128));
LIns *rangeBr = lir->insBranch(LIR_jt, rangeCnd, NULL);
LIns *tableVal = compileTableRead(chr, js_alnum);
if (!fails.append(lir->insBranch(LIR_jf, lir->insEqI_0(tableVal), NULL)))
@ -2729,45 +2729,45 @@ class RegExpNativeCompiler {
* (200A, max): 2028, 2029, 202F, 205F, 3000
*/
/* Below 0x20? */
LIns *tableRangeCnd = lir->ins2(LIR_ule, chr, lir->insImmI(0x20));
LIns *tableRangeCnd = lir->ins2(LIR_leui, chr, lir->insImmI(0x20));
LIns *tableRangeBr = lir->insBranch(LIR_jt, tableRangeCnd, NULL);
/* Fall through means *chr > 0x20. */
/* Handle (0x20,0xA0). */
LIns *asciiCnd = lir->ins2(LIR_ult, chr, lir->insImmI(0xA0));
LIns *asciiCnd = lir->ins2(LIR_ltui, chr, lir->insImmI(0xA0));
LIns *asciiMissBr = lir->insBranch(LIR_jt, asciiCnd, NULL);
/* Fall through means *chr >= 0xA0. */
/* Partition around [0x2000,0x200A]. */
LIns *belowCnd = lir->ins2(LIR_ult, chr, lir->insImmI(0x2000));
LIns *belowCnd = lir->ins2(LIR_ltui, chr, lir->insImmI(0x2000));
LIns *belowBr = lir->insBranch(LIR_jt, belowCnd, NULL);
LIns *aboveCnd = lir->ins2(LIR_ugt, chr, lir->insImmI(0x200A));
LIns *aboveCnd = lir->ins2(LIR_gtui, chr, lir->insImmI(0x200A));
LIns *aboveBr = lir->insBranch(LIR_jt, aboveCnd, NULL);
LIns *intervalMatchBr = lir->insBranch(LIR_j, NULL, NULL);
/* Handle [0xA0,0x2000). */
LIns *belowLbl = lir->ins0(LIR_label);
belowBr->setTarget(belowLbl);
LIns *eq1Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0xA0));
LIns *eq1Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0xA0));
LIns *eq1Br = lir->insBranch(LIR_jt, eq1Cnd, NULL);
LIns *eq2Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x1680));
LIns *eq2Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x1680));
LIns *eq2Br = lir->insBranch(LIR_jt, eq2Cnd, NULL);
LIns *eq3Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x180E));
LIns *eq3Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x180E));
LIns *eq3Br = lir->insBranch(LIR_jt, eq3Cnd, NULL);
LIns *belowMissBr = lir->insBranch(LIR_j, NULL, NULL);
/* Handle (0x200A, max). */
LIns *aboveLbl = lir->ins0(LIR_label);
aboveBr->setTarget(aboveLbl);
LIns *eq4Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x2028));
LIns *eq4Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x2028));
LIns *eq4Br = lir->insBranch(LIR_jt, eq4Cnd, NULL);
LIns *eq5Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x2029));
LIns *eq5Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x2029));
LIns *eq5Br = lir->insBranch(LIR_jt, eq5Cnd, NULL);
LIns *eq6Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x202F));
LIns *eq6Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x202F));
LIns *eq6Br = lir->insBranch(LIR_jt, eq6Cnd, NULL);
LIns *eq7Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x205F));
LIns *eq7Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x205F));
LIns *eq7Br = lir->insBranch(LIR_jt, eq7Cnd, NULL);
LIns *eq8Cnd = lir->ins2(LIR_eq, chr, lir->insImmI(0x3000));
LIns *eq8Cnd = lir->ins2(LIR_eqi, chr, lir->insImmI(0x3000));
LIns *eq8Br = lir->insBranch(LIR_jt, eq8Cnd, NULL);
LIns *aboveMissBr = lir->insBranch(LIR_j, NULL, NULL);
@ -2814,7 +2814,7 @@ class RegExpNativeCompiler {
return NULL;
}
return lir->ins2(LIR_piadd, pos, lir->insImmWord(2));
return lir->ins2(LIR_addp, pos, lir->insImmWord(2));
}
LIns *compileAlt(RENode *node, LIns *pos, bool atEnd, LInsList &fails)
@ -2977,7 +2977,7 @@ class RegExpNativeCompiler {
* we need to abort the loop or else we will loop forever.
*/
if (mayMatchEmpty(bodyRe)) {
LIns *eqCnd = lir->ins2(LIR_peq, iterBegin, iterEnd);
LIns *eqCnd = lir->ins2(LIR_eqp, iterBegin, iterEnd);
if (!kidFails.append(lir->insBranch(LIR_jt, eqCnd, NULL)))
return NULL;
}
@ -3012,9 +3012,9 @@ class RegExpNativeCompiler {
* conditionally executed, and we (currently) don't have real phi
* nodes, we need only consider insns defined in A and used in E.
*/
lir->ins1(LIR_plive, state);
lir->ins1(LIR_plive, cpend);
lir->ins1(LIR_plive, start);
lir->ins1(LIR_livep, state);
lir->ins1(LIR_livep, cpend);
lir->ins1(LIR_livep, start);
/* After the loop: reload 'pos' from memory and continue. */
targetCurrentPoint(kidFails);
@ -3083,13 +3083,13 @@ class RegExpNativeCompiler {
/* Fall-through from compileNode means success. */
lir->insStore(pos, state, offsetof(REGlobalData, stateStack), ACC_OTHER);
lir->ins0(LIR_regfence);
lir->ins1(LIR_ret, lir->insImmI(1));
lir->ins1(LIR_reti, lir->insImmI(1));
/* Stick return here so we don't have to jump over it every time. */
if (anchorFail) {
targetCurrentPoint(anchorFail);
lir->ins0(LIR_regfence);
lir->ins1(LIR_ret, lir->insImmI(0));
lir->ins1(LIR_reti, lir->insImmI(0));
}
/* Target failed matches. */
@ -3105,7 +3105,7 @@ class RegExpNativeCompiler {
/* Failed to match on first character, so fail whole match. */
lir->ins0(LIR_regfence);
lir->ins1(LIR_ret, lir->insImmI(0));
lir->ins1(LIR_reti, lir->insImmI(0));
return !outOfMemory();
}
@ -3113,13 +3113,13 @@ class RegExpNativeCompiler {
bool compileAnchoring(RENode *root, LIns *start)
{
/* Guard outer anchoring loop. Use <= to allow empty regexp match. */
LIns *anchorFail = lir->insBranch(LIR_jf, lir->ins2(LIR_ple, start, cpend), 0);
LIns *anchorFail = lir->insBranch(LIR_jf, lir->ins2(LIR_lep, start, cpend), 0);
if (!compileRootNode(root, start, anchorFail))
return false;
/* Outer loop increment. */
lir->insStore(lir->ins2(LIR_piadd, start, lir->insImmWord(2)), state,
lir->insStore(lir->ins2(LIR_addp, start, lir->insImmWord(2)), state,
offsetof(REGlobalData, skipped), ACC_OTHER);
return !outOfMemory();
@ -3144,8 +3144,8 @@ class RegExpNativeCompiler {
if (loopLabel) {
lir->insBranch(LIR_j, NULL, loopLabel);
LirBuffer* lirbuf = fragment->lirbuf;
lir->ins1(LIR_plive, lirbuf->state);
lir->ins1(LIR_plive, lirbuf->param1);
lir->ins1(LIR_livep, lirbuf->state);
lir->ins1(LIR_livep, lirbuf->param1);
}
Allocator &alloc = *JS_TRACE_MONITOR(cx).dataAlloc;

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

@ -8275,7 +8275,7 @@ TraceRecorder::i2d(LIns* i)
}
LIns*
TraceRecorder::d2i(LIns* f)
TraceRecorder::d2i(LIns* f, bool resultCanBeImpreciseIfFractional)
{
if (f->isImmD())
return lir->insImmI(js_DoubleToECMAInt32(f->immD()));
@ -8314,7 +8314,9 @@ TraceRecorder::d2i(LIns* f)
return lir->insCall(&js_String_p_charCodeAt_double_int_ci, args);
}
}
return lir->insCall(&js_DoubleToInt32_ci, &f);
return resultCanBeImpreciseIfFractional
? lir->ins1(LIR_d2i, f)
: lir->insCall(&js_DoubleToInt32_ci, &f);
}
LIns*
@ -8333,7 +8335,10 @@ TraceRecorder::makeNumberInt32(LIns* f)
JS_ASSERT(f->isD());
LIns* x;
if (!isPromote(f)) {
x = d2i(f);
// This means "convert double to int if it's integral, otherwise
// exit". We first convert the double to an int, then convert it back
// and exit if the two doubles don't match.
x = d2i(f, /* resultCanBeImpreciseIfFractional = */true);
guard(true, lir->ins2(LIR_feq, f, lir->ins1(LIR_i2f, x)), MISMATCH_EXIT);
} else {
x = demote(lir, f);
@ -13146,6 +13151,7 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
}
/* If not idx < min(length, capacity), stay on trace (and read value as undefined). */
JS_ASSERT(obj->isDenseArrayMinLenCapOk());
LIns* minLenCap =
addName(stobj_get_fslot(obj_ins, JSObject::JSSLOT_DENSE_ARRAY_MINLENCAP), "minLenCap");
LIns* br2 = lir->insBranch(LIR_jf,
@ -13176,6 +13182,7 @@ TraceRecorder::denseArrayElement(jsval& oval, jsval& ival, jsval*& vp, LIns*& v_
}
/* Guard array min(length, capacity). */
JS_ASSERT(obj->isDenseArrayMinLenCapOk());
LIns* minLenCap =
addName(stobj_get_fslot(obj_ins, JSObject::JSSLOT_DENSE_ARRAY_MINLENCAP), "minLenCap");
guard(true,

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

@ -1186,7 +1186,7 @@ class TraceRecorder
nanojit::LIns* s0, nanojit::LIns* s1);
nanojit::LIns* i2d(nanojit::LIns* i);
nanojit::LIns* d2i(nanojit::LIns* f);
nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false);
nanojit::LIns* f2u(nanojit::LIns* f);
JS_REQUIRES_STACK nanojit::LIns* makeNumberInt32(nanojit::LIns* f);
JS_REQUIRES_STACK nanojit::LIns* stringify(jsval& v);

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

@ -407,6 +407,11 @@ def PRMJ_Now():
*/
// We parameterize the delay count just so that shell builds can
// set it to 0 in order to get high-resolution benchmarking.
// 10 seems to be the number of calls to load with a blank homepage.
int CALIBRATION_DELAY_COUNT = 10;
JSInt64
PRMJ_Now(void)
{
@ -424,8 +429,7 @@ PRMJ_Now(void)
This does not appear to be needed on Vista as the timeBegin/timeEndPeriod
calls seem to immediately take effect. */
int thiscall = JS_ATOMIC_INCREMENT(&nCalls);
/* 10 seems to be the number of calls to load with a blank homepage */
if (thiscall <= 10) {
if (thiscall <= CALIBRATION_DELAY_COUNT) {
LowResTime(&ft);
return (FILETIME2INT64(ft)-win2un)/10L;
}

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

@ -3658,6 +3658,34 @@ Elapsed(JSContext *cx, uintN argc, jsval *vp)
return JS_FALSE;
}
static JSBool
Parent(JSContext *cx, uintN argc, jsval *vp)
{
if (argc != 1) {
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
jsval v = JS_ARGV(cx, vp)[0];
if (JSVAL_IS_PRIMITIVE(v)) {
JS_ReportError(cx, "Only objects have parents!");
return JS_FALSE;
}
JSObject *parent = JS_GetParent(cx, JSVAL_TO_OBJECT(v));
*vp = OBJECT_TO_JSVAL(parent);
/* Outerize if necessary. Embrace the ugliness! */
JSClass *clasp = JS_GET_CLASS(cx, parent);
if (clasp->flags & JSCLASS_IS_EXTENDED) {
JSExtendedClass *xclasp = reinterpret_cast<JSExtendedClass *>(clasp);
if (JSObjectOp outerize = xclasp->outerObject)
*vp = OBJECT_TO_JSVAL(outerize(cx, parent));
}
return JS_TRUE;
}
#ifdef XP_UNIX
#include <fcntl.h>
@ -3911,6 +3939,7 @@ static JSFunctionSpec shell_functions[] = {
JS_FN("parse", Parse, 1,0),
JS_FN("timeout", Timeout, 1,0),
JS_FN("elapsed", Elapsed, 0,0),
JS_FN("parent", Parent, 1,0),
JS_FS_END
};
@ -4018,7 +4047,8 @@ static const char *const shell_help_messages[] = {
"timeout([seconds])\n"
" Get/Set the limit in seconds for the execution time for the current context.\n"
" A negative value (default) means that the execution time is unlimited.",
"elapsed() Execution time elapsed for the current context.\n",
"elapsed() Execution time elapsed for the current context.",
"parent(obj) Returns the parent of obj.\n",
};
/* Help messages must match shell functions. */
@ -4980,6 +5010,13 @@ main(int argc, char **argv, char **envp)
argc--;
argv++;
#ifdef XP_WIN
// Set the timer calibration delay count to 0 so we get high
// resolution right away, which we need for precise benchmarking.
extern int CALIBRATION_DELAY_COUNT;
CALIBRATION_DELAY_COUNT = 0;
#endif
rt = JS_NewRuntime(64L * 1024L * 1024L);
if (!rt)
return 1;

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

@ -37,7 +37,7 @@
gTestfile = 'regress-313080.js';
var summary = "Regression - Do not crash calling __proto__, __parent__";
var summary = "Regression - Do not crash calling __proto__";
var BUGNUMBER = 313080;
var actual = 'No Crash';
var expect = 'No Crash';
@ -48,7 +48,6 @@ START(summary);
try
{
<element/>.__proto__();
<element/>.__parent__();
<element/>.function::__proto__();
}
catch(e)

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

@ -38,7 +38,7 @@
var gTestfile = '7.4-01.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 475834;
var summary = ' /**/ comments with newlines in them do not act as line breaks';
var summary = ' /**/ comments with newlines in them must act as line breaks';
var actual = '';
var expect = '';

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(1, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(2, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(3, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(4, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(5, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(6, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(7, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runDictionaryPropertyPresentTestsFraction(8, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(1, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(2, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(3, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(4, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(5, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(6, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(7, 8);

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

@ -0,0 +1,5 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
load("ecma_5/Object/defineProperty-setup.js");
runNonTerminalPropertyPresentTestsFraction(8, 8);

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

@ -578,7 +578,7 @@ TestRunner.prototype =
print("Starting test with old descriptor " + old.toSource() + "...");
for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j]);
self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
}
}
@ -587,6 +587,107 @@ TestRunner.prototype =
" completed!");
},
runNonTerminalPropertyPresentTestsFraction:
function runNonTerminalPropertyPresentTestsFraction(part, parts)
{
var self = this;
/*
* A plain old property to define on the object before redefining the
* originally-added property, to test redefinition of a property that's
* not also lastProperty. NB: we could loop over every possible
* descriptor here if we wanted, even try adding more than one, but we'd
* hit cubic complexity and worse, and SpiderMonkey only distinguishes by
* the mere presence of the middle property, not its precise details.
*/
var middleDefines =
[{
property: "middle",
descriptor:
{ value: 17, writable: true, configurable: true, enumerable: true }
}];
function nonTerminalPropertyPresentTests()
{
print("Running non-terminal already-present tests now...");
var total = VALID_DESCRIPTORS.length;
var start = Math.floor((part - 1) / parts * total);
var end = Math.floor(part / parts * total);
for (var i = start; i < end; i++)
{
var old = VALID_DESCRIPTORS[i];
print("Starting test with old descriptor " + old.toSource() + "...");
for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
{
self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
middleDefines);
}
}
}
this._runTestSet(nonTerminalPropertyPresentTests,
"Non-terminal property-present fraction " +
part + " of " + parts + " completed!");
},
runDictionaryPropertyPresentTestsFraction:
function runDictionaryPropertyPresentTestsFraction(part, parts)
{
var self = this;
/*
* Add and readd properties such that the scope for the object is in
* dictionary mode.
*/
var middleDefines =
[
{
property: "mid1",
descriptor:
{ value: 17, writable: true, configurable: true, enumerable: true }
},
{
property: "mid2",
descriptor:
{ value: 17, writable: true, configurable: true, enumerable: true }
},
{
property: "mid1",
descriptor:
{ get: function g() { }, set: function s(v){}, configurable: false,
enumerable: true }
},
];
function dictionaryPropertyPresentTests()
{
print("Running dictionary already-present tests now...");
var total = VALID_DESCRIPTORS.length;
var start = Math.floor((part - 1) / parts * total);
var end = Math.floor(part / parts * total);
for (var i = start; i < end; i++)
{
var old = VALID_DESCRIPTORS[i];
print("Starting test with old descriptor " + old.toSource() + "...");
for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
{
self._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j],
middleDefines);
}
}
}
this._runTestSet(dictionaryPropertyPresentTests,
"Dictionary property-present fraction " +
part + " of " + parts + " completed!");
},
// HELPERS
@ -600,7 +701,7 @@ TestRunner.prototype =
print("Starting test with old descriptor " + old.toSource() + "...");
for (var j = 0, sz2 = VALID_DESCRIPTORS.length; j < sz2; j++)
this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j]);
this._runSinglePropertyPresentTest(old, VALID_DESCRIPTORS[j], []);
}
},
_runTestSet: function _runTestSet(fun, completeMessage)
@ -724,7 +825,8 @@ TestRunner.prototype =
return;
}
},
_runSinglePropertyPresentTest: function _runSinglePropertyPresentTest(old, add)
_runSinglePropertyPresentTest:
function _runSinglePropertyPresentTest(old, add, middleDefines)
{
var nativeObj = NativeTest.newObject();
var reimplObj = ReimplTest.newObject();
@ -781,6 +883,35 @@ TestRunner.prototype =
return;
}
// Now add (or even readd) however many properties were specified between
// the original property to add and the new one, to test redefining
// non-last-properties and properties in scopes in dictionary mode.
for (var i = 0, sz = middleDefines.length; i < sz; i++)
{
var middle = middleDefines[i];
var prop = middle.property;
var desc = middle.descriptor;
try
{
NativeTest.defineProperty(nativeObj, prop, desc);
ReimplTest.defineProperty(reimplObj, prop, desc);
}
catch (e)
{
this._log("failure defining middle descriptor: " + desc.toSource() +
", error " + e);
return;
}
// Sanity check
var nativeDesc = NativeTest.getDescriptor(nativeObj, prop);
var reimplDesc = ReimplTest.getDescriptor(reimplObj, prop);
compareDescriptors(nativeDesc, reimplDesc);
compareDescriptors(nativeDesc, desc);
}
try
{
NativeTest.defineProperty(nativeObj, "foo", add);
@ -900,3 +1031,72 @@ TestRunner.prototype =
}
}
};
function runDictionaryPropertyPresentTestsFraction(PART, PARTS)
{
var testfile =
'15.2.3.6-dictionary-redefinition-' + PART + '-of-' + PARTS + '.js';
var BUGNUMBER = 560566;
var summary =
'ES5 Object.defineProperty(O, P, Attributes): dictionary redefinition ' +
PART + ' of ' + PARTS;
print(BUGNUMBER + ": " + summary);
try
{
new TestRunner().runDictionaryPropertyPresentTestsFraction(PART, PARTS);
}
catch (e)
{
throw "Error thrown during testing: " + e +
" at line " + e.lineNumber + "\n" +
(e.stack
? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
: "");
}
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete!");
}
function runNonTerminalPropertyPresentTestsFraction(PART, PARTS)
{
var PART = 1, PARTS = 4;
var gTestfile =
'15.2.3.6-middle-redefinition-' + PART + '-of-' + PARTS + '.js';
var BUGNUMBER = 560566;
var summary =
'ES5 Object.defineProperty(O, P, Attributes): middle redefinition ' +
PART + ' of ' + PARTS;
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
try
{
new TestRunner().runNonTerminalPropertyPresentTestsFraction(PART, PARTS);
}
catch (e)
{
throw "Error thrown during testing: " + e +
" at line " + e.lineNumber + "\n" +
(e.stack
? "Stack: " + e.stack.split("\n").slice(2).join("\n") + "\n"
: "");
}
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("Tests complete!");
}

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

@ -11,3 +11,19 @@ skip-if(!xulRuntime.shell) script 15.2.3.6-redefinition-3-of-4.js # uses shell l
skip-if(!xulRuntime.shell) script 15.2.3.6-redefinition-4-of-4.js # uses shell load() function
script 15.2.3.7-01.js
script 15.2.3.14-01.js # does not use reportCompare
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-1-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-2-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-3-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-4-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-5-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-6-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-7-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-middle-redefinition-8-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-1-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-2-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-3-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-4-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-5-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-6-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-7-of-8.js # uses shell load() function
skip-if(!xulRuntime.shell) script 15.2.3.6-dictionary-redefinition-8-of-8.js # uses shell load() function

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

@ -13,7 +13,6 @@ script regress-104077.js
script regress-164697.js
script regress-178722.js
script regress-192465.js
script regress-220584.js
script regress-225831.js
script regress-226078.js
script regress-226507.js
@ -32,7 +31,6 @@ script regress-311161.js
script regress-311583.js
script regress-311792-01.js
script regress-311792-02.js
script regress-312278.js
script regress-313500.js
script regress-313763.js
script regress-313803.js
@ -196,7 +194,6 @@ script regress-452168.js
script regress-452178.js
script regress-452329.js
script regress-452338.js
script regress-452372.js
script regress-452565.js
script regress-453249.js
script regress-454040.js

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

@ -38,7 +38,7 @@
var gTestfile = 'regress-164697.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 164697;
var summary = '(instance.__parent__ == constructor.__parent__)';
var summary = '(parent(instance) == parent(constructor))';
var actual = '';
var expect = '';
@ -61,13 +61,10 @@ runtest('new Function(";")', 'Function');
runtest('[]', 'Array');
runtest('new Array()', 'Array');
runtest('""', 'String');
runtest('new String()', 'String');
runtest('true', 'Boolean');
runtest('new Boolean()', 'Boolean');
runtest('1', 'Number');
runtest('new Number("1")', 'Number');
runtest('new Date()', 'Date');
@ -82,19 +79,23 @@ function runtest(myinstance, myconstructor)
var expr;
var actual;
try
if (typeof parent === "function")
{
expr = '(' + myinstance + ').__parent__ == ' +
myconstructor + '.__parent__';
printStatus(expr);
actual = eval(expr).toString();
}
catch(ex)
{
actual = ex + '';
}
try
{
expr =
'parent(' + myinstance + ') == ' +
'parent(' + myconstructor + ')';
printStatus(expr);
actual = eval(expr).toString();
}
catch(ex)
{
actual = ex + '';
}
reportCompare(expect, actual, expr);
reportCompare(expect, actual, expr);
}
try
{

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

@ -1,147 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corp.
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* igor@fastmail.fm, pschwartau@netscape.com
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
*
* Date: 29 Sep 2003
* SUMMARY: Testing __parent__ and __proto__ of Script object
*
* See http://bugzilla.mozilla.org/show_bug.cgi?id=220584
*/
//-----------------------------------------------------------------------------
var gTestfile = 'regress-220584.js';
var UBound = 0;
var BUGNUMBER = 220584;
var summary = 'Testing __parent__ and __proto__ of Script object';
var status = '';
var statusitems = [];
var actual = '';
var actualvalues = [];
var expect= '';
var expectedvalues = [];
var s;
// invoke |Script| as a function
status = inSection(1);
if (typeof Script == 'undefined')
{
reportCompare("Script not defined, Test skipped.",
"Script not defined, Test skipped.",
summary);
}
else
{
s = Script('1;');
actual = s instanceof Object;
expect = true;
addThis();
status = inSection(2);
actual = (s.__parent__ == undefined) || (s.__parent__ == null);
expect = false;
addThis();
status = inSection(3);
actual = (s.__proto__ == undefined) || (s.__proto__ == null);
expect = false;
addThis();
status = inSection(4);
actual = (s + '').length > 0;
expect = true;
addThis();
}
// invoke |Script| as a constructor
status = inSection(5);
if (typeof Script == 'undefined')
{
print('Test skipped. Script not defined.');
}
else
{
s = new Script('1;');
actual = s instanceof Object;
expect = true;
addThis();
status = inSection(6);
actual = (s.__parent__ == undefined) || (s.__parent__ == null);
expect = false;
addThis();
status = inSection(7);
actual = (s.__proto__ == undefined) || (s.__proto__ == null);
expect = false;
addThis();
status = inSection(8);
actual = (s + '').length > 0;
expect = true;
addThis();
}
//-----------------------------------------------------------------------------
test();
//-----------------------------------------------------------------------------
function addThis()
{
statusitems[UBound] = status;
actualvalues[UBound] = actual;
expectedvalues[UBound] = expect;
UBound++;
}
function test()
{
enterFunc('test');
printBugNumber(BUGNUMBER);
printStatus(summary);
for (var i=0; i<UBound; i++)
{
reportCompare(expectedvalues[i], actualvalues[i], statusitems[i]);
}
exitFunc ('test');
}

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

@ -1,75 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2005
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): Igor Bukanov
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gTestfile = 'regress-312278.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 312278;
var summary = 'Do no access GC-ed object in Error.prototype.toSource';
var actual = 'No Crash';
var expect = 'No Crash';
printBugNumber(BUGNUMBER);
printStatus (summary);
function wrapInsideWith(obj)
{
var f;
with (obj) {
f = function() { }
}
return f.__parent__;
}
function customToSource()
{
return "customToSource "+this;
}
Error.prototype.__defineGetter__('message', function() {
var obj = {
toSource: "something"
}
obj.__defineGetter__('toSource', function() {
gc();
return customToSource;
});
return wrapInsideWith(obj);
});
printStatus(Error.prototype.toSource());
reportCompare(expect, actual, summary);

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

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): Jesse Ruderman
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gTestfile = 'regress-452372.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 452372;
var summary = 'Do not assert with JIT: entry->kpc == (jsbytecode*) atom';
var actual = 'No Crash';
var expect = 'No Crash';
//-----------------------------------------------------------------------------
test();
//-----------------------------------------------------------------------------
function test()
{
enterFunc ('test');
printBugNumber(BUGNUMBER);
printStatus (summary);
jit(true);
eval("(function() { for (var j = 0; j < 4; ++j) { /x/.__parent__; } })")();
jit(false);
reportCompare(expect, actual, summary);
exitFunc ('test');
}

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

@ -32,7 +32,6 @@ script regress-355052-03.js
script regress-355145.js
script regress-355410.js
script regress-355512.js
script regress-355578.js
script regress-355583.js
script regress-363040-01.js
script regress-363040-02.js

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

@ -1,78 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is JavaScript Engine testing utilities.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s): shutdown
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
var gTestfile = 'regress-355578.js';
//-----------------------------------------------------------------------------
var BUGNUMBER = 355578;
var summary = 'block object access to dead JSStackFrame';
var actual = '';
var expect = '';
//-----------------------------------------------------------------------------
test();
//-----------------------------------------------------------------------------
function test()
{
enterFunc ('test');
printBugNumber(BUGNUMBER);
printStatus (summary);
var filler = "", rooter = {};
for(var i = 0; i < 0x70/2; i++)
{
filler += "\u5050";
}
var blkobj = function() { let x; yield function(){}.__parent__; }().next();
gc();
for(var i = 0; i < 1024; i++)
{
rooter[i] = filler + i;
}
try
{
print(blkobj.x);
}
catch(ex)
{
}
reportCompare(expect, actual, summary);
exitFunc ('test');
}

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

@ -58,7 +58,7 @@ function test()
try
{
(function() {
let b = function(){}.__parent__;
let b = parent(function(){});
print(b[1] = throwError);
})();
}

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

@ -27,7 +27,7 @@ function makeWorkerFn(id) {
for (n in bar) {
for (m in bar[n]) {}
}
for (n in {}.__parent__) {}
for (n in parent({})) {}
};
}
@ -42,8 +42,8 @@ var actual;
expect = actual = 'No crash';
if (typeof scatter == 'undefined') {
print('Test skipped. scatter not defined.');
} else if (!("__parent__" in {})) {
print('Test skipped. __parent__ not defined.');
} else if (typeof parent === "undefined") {
print('Test skipped, no parent() function.');
} else {
for (let i = 0; i < LOOP_COUNT; i++) {
foo = 0;

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

@ -8,9 +8,14 @@ script regress-541255-3.js
script regress-541255-4.js
script regress-541455.js
script regress-546615.js
script regress-551763-0.js
script regress-551763-1.js
script regress-551763-2.js
script regress-555246-0.js
fails script regress-555246-1.js
script regress-559438.js
script regress-560101.js
script regress-560998-1.js
script regress-560998-2.js
script regress-563210.js
script regress-563221.js

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

@ -0,0 +1,27 @@
(function() {
var o = {'arguments': 42};
with (o) { // Definitely forces heavyweight.
// Note syntax is not a property access.
reportCompare(delete arguments, true,
"arguments property deletion within with block");
}
reportCompare('arguments' in o, false,
"property deletion observable");
})();
(function() {
var o = {'arguments': 42};
delete o.arguments;
reportCompare('arguments' in o, false,
"arguments property deletion with property access syntax");
})();
(function() {
var arguments = 42; // Forces heavyweight.
reportCompare(delete arguments, false,
"arguments variable");
})();
(function() {
reportCompare(delete arguments, false, "arguments object");
})();

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

@ -0,0 +1,4 @@
/* Check we can delete arguments in the global space. */
arguments = 42;
reportCompare(delete arguments, true, "arguments defined as global");

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

@ -0,0 +1,3 @@
/* Check we can't delete a var-declared arguments in global space. */
var arguments = 42;
reportCompare(delete arguments, false, "arguments defined as global variable");

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

@ -0,0 +1,23 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributors: Gary Kwong and Nicholas Nethercote
*/
gTestfile = 'regress-563210';
if (typeof gczeal != 'undefined' && typeof gc != 'undefined') {
try
{
try {
__defineGetter__("x", gc)
} catch (e) {}
gczeal(1)
print(x)(Array(-8))
}
catch(ex)
{
}
}
reportCompare("no assertion failure", "no assertion failure", "bug 563210");

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

@ -0,0 +1,8 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
// Contributor: Jason Orendorff <jorendorff@mozilla.com>
"" + eval("(function () { if (x) ; else if (y) n(); else { " + Array(10000).join("e;") + " } });");
if (this.reportCompare)
reportCompare(0, 0, "ok");

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

@ -1,26 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
function mk() {
return (function () {});
}
function f() {
var j = 55;
var f = function () {
return j;
};
var g = function() {};
var a = [ mk(), f, g, mk(), mk() ];
for (var i = 0; i < 5; ++i) {
a[i].p = 99;
}
}
f();
for (var i = 0; i < 9; i++)
({__parent__: []} = []);

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

@ -1,2 +0,0 @@
for (var i = 0; i < 9; i++)
({__parent__: []} = []);

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

@ -223,7 +223,7 @@ interface nsIXPCComponents_Utils : nsISupports
*
* Returns the global object with which the given object is associated.
*
* @param obj The JavaScript object whose parent is to be gotten.
* @param obj The JavaScript object whose global is to be gotten.
* @return the corresponding global.
*/
void /* JSObject */ getGlobalForObject(/* in JSObject obj */);

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

@ -759,6 +759,24 @@ Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
return JS_TRUE;
}
static JSBool
Parent(JSContext *cx, uintN argc, jsval *vp)
{
if (argc != 1) {
JS_ReportError(cx, "Wrong number of arguments");
return JS_FALSE;
}
jsval v = JS_ARGV(cx, vp)[0];
if (JSVAL_IS_PRIMITIVE(v)) {
JS_ReportError(cx, "Only objects have parents!");
return JS_FALSE;
}
*vp = OBJECT_TO_JSVAL(JS_GetParent(cx, JSVAL_TO_OBJECT(v)));
return JS_TRUE;
}
static JSFunctionSpec glob_functions[] = {
{"print", Print, 0,0,0},
{"readline", ReadLine, 1,0,0},
@ -774,6 +792,7 @@ static JSFunctionSpec glob_functions[] = {
#endif
{"clear", Clear, 1,0,0},
{"options", Options, 0,0,0},
JS_FN("parent", Parent, 1,0),
#ifdef DEBUG
{"dumpHeap", DumpHeap, 5,0,0},
#endif

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

@ -594,9 +594,8 @@ XPC_COW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
}
if (interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PROTO) ||
interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_PARENT) ||
interned_id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS)) {
// No getting or setting __proto__ or __parent__ on my object.
// No getting or setting __proto__ on my object.
return ThrowException(NS_ERROR_INVALID_ARG, cx); // XXX better error message
}

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

@ -1382,7 +1382,7 @@ XPCNativeWrapper::CreateExplicitWrapper(JSContext *cx,
// parents for it.
JS_LockGCThing(cx, wrapperObj);
// A deep XPCNativeWrapper has a __parent__ chain that mirrors its
// A deep XPCNativeWrapper has a parent chain that mirrors its
// XPCWrappedNative's chain.
if (!MirrorWrappedNativeParent(cx, wrappedNative, &parent))
return JS_FALSE;

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

@ -62,7 +62,6 @@ const char* XPCJSRuntime::mStrings[] = {
"item", // IDX_ITEM
"__proto__", // IDX_PROTO
"__iterator__", // IDX_ITERATOR
"__parent__", // IDX_PARENT
"__exposedProps__" // IDX_EXPOSEDPROPS
};

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

@ -669,7 +669,6 @@ public:
IDX_ITEM ,
IDX_PROTO ,
IDX_ITERATOR ,
IDX_PARENT ,
IDX_EXPOSEDPROPS ,
IDX_TOTAL_COUNT // just a count of the above
};
@ -3013,7 +3012,7 @@ public:
* @param s the native object we're working with
* @param type the type of object that s is
* @param iid the interface of s that we want
* @param scope the default scope to put on the new JSObject's __parent__
* @param scope the default scope to put on the new JSObject's parent
* chain
* @param pErr [out] relevant error code, if any.
*/
@ -3044,8 +3043,7 @@ public:
* @param Interface the interface of src that we want
* @param cache the wrapper cache for src (may be null, in which case src
* will be QI'ed to get the cache)
* @param scope the default scope to put on the new JSObject's __parent__
* chain
* @param scope the default scope to put on the new JSObject's parent chain
* @param allowNativeWrapper if true, this method may wrap the resulting
* JSObject in an XPCNativeWrapper and return that, as needed.
* @param isGlobal
@ -3100,8 +3098,7 @@ public:
* @param type the type of objects in the array
* @param iid the interface of each object in the array that we want
* @param count the number of items in the array
* @param scope the default scope to put on the new JSObjects' __parent__
* chain
* @param scope the default scope to put on the new JSObjects' parent chain
* @param pErr [out] relevant error code, if any.
*/
static JSBool NativeArray2JS(XPCLazyCallContext& ccx,
@ -4275,8 +4272,7 @@ public:
*
* @param ccx the context for the whole procedure
* @param variant the variant to convert
* @param scope the default scope to put on the new JSObject's __parent__
* chain
* @param scope the default scope to put on the new JSObject's parent chain
* @param pErr [out] relevant error code, if any.
* @param pJSVal [out] the resulting jsval.
*/

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

@ -1,74 +0,0 @@
const LOOP_COUNT = 10000;
const THREAD_COUNT = 10;
const nsIThread = Components.interfaces.nsIThread;
const ThreadContractID = "@mozilla.org/thread;1";
const Thread = new Components.Constructor(ThreadContractID, "nsIThread", "init");
var foo;
var bar;
function threadProc() {
foo = this.id+1;
bar[this.id] = {p : 0};
var n, m;
for(n in bar) {
// Uncommenting the line below makes this a lot more likely to deadlock.
for(m in bar[n]) {}
}
// Commented this because I was thinking that the printf impl being called
// on so many thread might be contributing to some apparent memory
// corruption cases.
// print(" printed from other thread "+this.id+". foo is: "+foo);
for(n in this.__parent__) /* print(n) */;
}
function runThreads() {
print(" printed from main thread. foo is "+foo);
var threads = new Array(THREAD_COUNT);
var i;
for(i = 0; i < THREAD_COUNT; i++) {
var runable = {run : threadProc, id : i};
threads[i] = new Thread(runable, 0,
nsIThread.PRIORITY_NORMAL,
nsIThread.SCOPE_GLOBAL,
nsIThread.STATE_JOINABLE);
}
print(" printed from main thread. foo is "+foo);
// var main_thread = threads[0].currentThread;
for(i = THREAD_COUNT-1; i >= 0; i--) {
// main_thread.sleep(1);
threads[i].join();
}
print(" printed from main thread. foo is "+foo);
}
var total_interval = 0;
for(i = 0; i < LOOP_COUNT; i++) {
var start_time = new Date().getTime()/1000;
foo = 0;
bar = new Array(THREAD_COUNT);
print("--- loop number "+i);
runThreads();
var end_time = new Date().getTime()/1000;
var interval = parseInt(100*(end_time - start_time),10)/100;
print(" Interval = "+interval+ " seconds.");
// ignore first loop
if(i) {
total_interval += end_time - start_time;
var average_interval = parseInt(100*(total_interval / i),10)/100
print("Average Interval = "+average_interval+" seconds.");
}
}

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

@ -7,10 +7,16 @@
.getInterface(Components.interfaces.nsIDOMWindowUtils);
ok(utils.getClassName(wrapper) === expected, note);
}
function check_parent(ok, obj, expected, note) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var utils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
ok(utils.getParent(obj) === expected, note);
}
function run_test(ok, xpcnw, sjow) {
// both wrappers should point to our window: XOW
check_wrapper(ok, ok, "Function", "functions are wrapped properly")
ok(ok.__parent__ == window, "ok is parented correctly");
check_parent(ok, ok, window, "ok is parented correctly");
check_wrapper(ok, xpcnw, "XPCCrossOriginWrapper", "XPCNWs are transformed correctly");
check_wrapper(ok, sjow, "XPCCrossOriginWrapper", "SJOWs are transformed correctly");

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

@ -62,8 +62,7 @@ function COWTests() {
var empty = {};
isProp(getCOW(empty), "foo", undefined, "empty.foo is undefined");
const PROPS_TO_TEST = ['foo', '__parent__', '__proto__',
'prototype', 'constructor'];
const PROPS_TO_TEST = ['foo', '__proto__', 'prototype', 'constructor'];
var strict = { __exposedProps__: {} };
var strictCOW = getCOW(strict);

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

@ -20,11 +20,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=366645
/** Test for Bug 366645 **/
function getParent(obj) {
return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.getParent(obj);
}
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var Cc = Components.classes;
var Ci = Components.interfaces;
var table = Cc["@mozilla.org/url-classifier/table;1?type=url"].createInstance();
var componentScope = table.wrappedJSObject.__parent__;
var componentScope = getParent(table.wrappedJSObject);
ok(!!componentScope, "unable to get wrapped js object");
var PROT_EnchashDecrypter = componentScope.PROT_EnchashDecrypter;

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

@ -45,6 +45,18 @@ const Ci = Components.interfaces;
#expand const CTYPES_TEST_LIB = __CTYPES_TEST_LIB__;
function getParent(obj, fun)
{
if (typeof parent === "function")
fun(parent(obj));
}
function checkParentIsCTypes(o)
{
function parentIsCTypes(p) { do_check_true(p === ctypes); }
getParent(o, parentIsCTypes);
}
function do_check_throws(f, type, stack)
{
if (!stack)
@ -233,16 +245,20 @@ function run_abstract_class_tests()
do_check_class(ctypes.CType, "Function");
do_check_class(ctypes.CType.prototype, "CType");
do_check_true(ctypes.CType.__parent__ === ctypes);
do_check_true(ctypes.CType.__proto__ === ctypes.__parent__.Function.prototype);
do_check_true(ctypes.CType instanceof ctypes.__parent__.Function);
checkParentIsCTypes(ctypes.CType);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.CType) === p.Function.prototype);
do_check_true(ctypes.CType instanceof p.Function);
});
do_check_true(ctypes.CType.hasOwnProperty("prototype"));
do_check_throws(function() { ctypes.CType.prototype(); }, Error);
do_check_throws(function() { new ctypes.CType.prototype() }, Error);
do_check_true(ctypes.CType.prototype.__parent__ === ctypes);
do_check_true(ctypes.CType.prototype.__proto__ === ctypes.__parent__.Function.prototype);
do_check_true(ctypes.CType.prototype instanceof ctypes.__parent__.Function);
checkParentIsCTypes(ctypes.CType.prototype);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.CType.prototype) === p.Function.prototype);
do_check_true(ctypes.CType.prototype instanceof p.Function);
});
do_check_true(ctypes.CType.prototype.hasOwnProperty("constructor"));
do_check_true(ctypes.CType.prototype.constructor === ctypes.CType);
@ -270,13 +286,15 @@ function run_abstract_class_tests()
do_check_class(ctypes.CData, "Function");
do_check_class(ctypes.CData.prototype, "CData");
do_check_true(ctypes.CData.__parent__ === ctypes);
checkParentIsCTypes(ctypes.CData);
do_check_true(ctypes.CData.__proto__ === ctypes.CType.prototype);
do_check_true(ctypes.CData instanceof ctypes.CType);
do_check_true(ctypes.CData.hasOwnProperty("prototype"));
do_check_true(ctypes.CData.prototype.__parent__ === ctypes);
do_check_true(ctypes.CData.prototype.__proto__ === ctypes.__parent__.Object.prototype);
checkParentIsCTypes(ctypes.CData.prototype);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.CData.prototype) === p.Object.prototype);
});
do_check_true(ctypes.CData.prototype.hasOwnProperty("constructor"));
do_check_true(ctypes.CData.prototype.constructor === ctypes.CData);
@ -303,12 +321,14 @@ function run_Int64_tests() {
do_check_class(ctypes.Int64, "Function");
do_check_class(ctypes.Int64.prototype, "Int64");
do_check_true(ctypes.Int64.__parent__ === ctypes);
do_check_true(ctypes.Int64.__proto__ === ctypes.__parent__.Function.prototype);
checkParentIsCTypes(ctypes.Int64);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.Int64) === p.Function.prototype);
do_check_true(Object.getPrototypeOf(ctypes.Int64.prototype) === p.Object.prototype);
});
do_check_true(ctypes.Int64.hasOwnProperty("prototype"));
do_check_true(ctypes.Int64.prototype.__parent__ === ctypes);
do_check_true(ctypes.Int64.prototype.__proto__ === ctypes.__parent__.Object.prototype);
checkParentIsCTypes(ctypes.Int64.prototype);
do_check_true(ctypes.Int64.prototype.hasOwnProperty("constructor"));
do_check_true(ctypes.Int64.prototype.constructor === ctypes.Int64);
@ -326,7 +346,7 @@ function run_Int64_tests() {
do_check_throws(function() { ctypes.Int64.prototype.toSource(); }, Error);
let i = ctypes.Int64(0);
do_check_true(i.__parent__ === ctypes);
checkParentIsCTypes(i);
do_check_true(i.__proto__ === ctypes.Int64.prototype);
do_check_true(i instanceof ctypes.Int64);
@ -480,12 +500,16 @@ function run_UInt64_tests() {
do_check_class(ctypes.UInt64, "Function");
do_check_class(ctypes.UInt64.prototype, "UInt64");
do_check_true(ctypes.UInt64.__parent__ === ctypes);
do_check_true(ctypes.UInt64.__proto__ === ctypes.__parent__.Function.prototype);
checkParentIsCTypes(ctypes.UInt64);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.UInt64) === p.Function.prototype);
});
do_check_true(ctypes.UInt64.hasOwnProperty("prototype"));
do_check_true(ctypes.UInt64.prototype.__parent__ === ctypes);
do_check_true(ctypes.UInt64.prototype.__proto__ === ctypes.__parent__.Object.prototype);
checkParentIsCTypes(ctypes.UInt64.prototype);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(ctypes.UInt64.prototype) === p.Object.prototype);
});
do_check_true(ctypes.UInt64.prototype.hasOwnProperty("constructor"));
do_check_true(ctypes.UInt64.prototype.constructor === ctypes.UInt64);
@ -503,7 +527,7 @@ function run_UInt64_tests() {
do_check_throws(function() { ctypes.UInt64.prototype.toSource(); }, Error);
let i = ctypes.UInt64(0);
do_check_true(i.__parent__ === ctypes);
checkParentIsCTypes(i);
do_check_true(i.__proto__ === ctypes.UInt64.prototype);
do_check_true(i instanceof ctypes.UInt64);
@ -720,11 +744,11 @@ function run_basic_class_tests(t)
do_check_class(t, "CType");
do_check_class(t.prototype, "CData");
do_check_true(t.__parent__ === ctypes);
checkParentIsCTypes(t);
do_check_true(t.__proto__ === ctypes.CType.prototype);
do_check_true(t instanceof ctypes.CType);
do_check_true(t.prototype.__parent__ === ctypes);
checkParentIsCTypes(t.prototype);
do_check_true(t.prototype.__proto__ === ctypes.CData.prototype);
do_check_true(t.prototype instanceof ctypes.CData);
do_check_true(t.prototype.constructor === t);
@ -740,7 +764,7 @@ function run_basic_class_tests(t)
// Test that an instance 'd' of 't' is a CData.
let d = t();
do_check_class(d, "CData");
do_check_true(d.__parent__ === ctypes);
checkParentIsCTypes(d);
do_check_true(d.__proto__ === t.prototype);
do_check_true(d instanceof t);
do_check_true(d.constructor === t);
@ -1265,11 +1289,13 @@ function run_type_ctor_class_tests(c, t, t2, props, fns, instanceProps, instance
do_check_class(c, "Function");
do_check_class(c.prototype, "CType");
do_check_true(c.__parent__ === ctypes);
do_check_true(c.__proto__ === ctypes.__parent__.Function.prototype);
do_check_true(c instanceof ctypes.__parent__.Function);
checkParentIsCTypes(c);
getParent(ctypes, function(p) {
do_check_true(Object.getPrototypeOf(c) === p.Function.prototype);
do_check_true(c instanceof p.Function);
});
do_check_true(c.prototype.__parent__ === ctypes);
checkParentIsCTypes(c.prototype);
do_check_true(c.prototype.__proto__ === ctypes.CType.prototype);
do_check_true(c.prototype instanceof ctypes.CType);
do_check_true(c.prototype.constructor === c);
@ -1291,18 +1317,18 @@ function run_type_ctor_class_tests(c, t, t2, props, fns, instanceProps, instance
do_check_class(t, "CType");
do_check_class(t.prototype, "CData");
do_check_true(t.__parent__ === ctypes);
checkParentIsCTypes(t);
do_check_true(t.__proto__ === c.prototype);
do_check_true(t instanceof c);
do_check_true(t.prototype.__parent__ === ctypes);
checkParentIsCTypes(t.prototype);
do_check_class(t.prototype.__proto__, "CData");
// 't.prototype.__proto__' is the common ancestor of all types constructed
// from 'c'; while not available from 'c' directly, it should be identically
// equal to 't2.prototype.__proto__' where 't2' is a different CType
// constructed from 'c'.
do_check_true(t.prototype.__proto__ === t2.prototype.__proto__);
do_check_true(t.prototype.__proto__.__parent__ === ctypes);
checkParentIsCTypes(Object.getPrototypeOf(t.prototype));
do_check_true(t.prototype.__proto__.__proto__ === ctypes.CData.prototype);
do_check_true(t.prototype instanceof ctypes.CData);
do_check_true(t.prototype.constructor === t);
@ -1337,7 +1363,7 @@ function run_type_ctor_class_tests(c, t, t2, props, fns, instanceProps, instance
if (t.__proto__ != ctypes.FunctionType.prototype) {
let d = t();
do_check_class(d, "CData");
do_check_true(d.__parent__ === ctypes);
checkParentIsCTypes(d);
do_check_true(d.__proto__ === t.prototype);
do_check_true(d instanceof t);
do_check_true(d.constructor === t);

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

@ -18,11 +18,17 @@ mochitest framework.
<script class="testbody" type="text/javascript">
<![CDATA[
function getParent(obj) {
return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.getParent(obj);
}
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var Cc = Components.classes;
var Ci = Components.interfaces;
var table = Cc["@mozilla.org/url-classifier/table;1?type=url"].createInstance();
var componentScope = table.wrappedJSObject.__parent__;
var componentScope = getParent(table.wrappedJSObject);
ok(!!componentScope, "unable to get wrapped js object");
////// Test PROT_EnchashDecrypter methods //////