mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-28 12:45:27 +00:00
Bug 670759 - Add GlobalObject::createBlankPrototype to abstract creation of prototype objects other than Object.prototype. r=bhackett
This commit is contained in:
parent
312831a434
commit
16572ce292
@ -814,33 +814,28 @@ static JSFunctionSpec regexp_methods[] = {
|
||||
};
|
||||
|
||||
JSObject *
|
||||
js_InitRegExpClass(JSContext *cx, JSObject *global)
|
||||
js_InitRegExpClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(global->isGlobal());
|
||||
JS_ASSERT(global->isNative());
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
/* Create and initialize RegExp.prototype. */
|
||||
JSObject *objectProto;
|
||||
if (!js_GetClassPrototype(cx, global, JSProto_Object, &objectProto))
|
||||
return NULL;
|
||||
JS_ASSERT(objectProto);
|
||||
GlobalObject *global = obj->asGlobal();
|
||||
|
||||
JSObject *proto = NewObject<WithProto::Class>(cx, &js_RegExpClass, objectProto, global);
|
||||
JSObject *proto = global->createBlankPrototype(cx, &js_RegExpClass);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
AlreadyIncRefed<RegExp> re = RegExp::create(cx, cx->runtime->emptyString, 0, NULL);
|
||||
if (!re)
|
||||
return NULL;
|
||||
#ifdef DEBUG
|
||||
assertSameCompartment(cx, proto, re->compartment);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Associate the empty regular expression with RegExp.prototype, and define
|
||||
* the initial non-method properties of any regular expression instance.
|
||||
* These must be added before methods to preserve slot layout.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
assertSameCompartment(cx, proto, re->compartment);
|
||||
#endif
|
||||
if (!proto->initRegExp(cx, re.get()))
|
||||
return NULL;
|
||||
|
||||
@ -882,17 +877,6 @@ js_InitRegExpClass(JSContext *cx, JSObject *global)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure proto's emptyShape is available to be shared by objects of
|
||||
* this class. JSObject::emptyShape is a one-slot cache. If we omit this,
|
||||
* some other class could snap it up. (The risk is particularly great for
|
||||
* Object.prototype.)
|
||||
*
|
||||
* All callers of JSObject::initSharingEmptyShape depend on this.
|
||||
*/
|
||||
if (!proto->getEmptyShape(cx, &js_RegExpClass, FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
|
||||
/* Install the fully-constructed RegExp and RegExp.prototype in global. */
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_RegExp, ctor, proto))
|
||||
return NULL;
|
||||
|
@ -3163,24 +3163,13 @@ StringObject::assignInitialShape(JSContext *cx)
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitStringClass(JSContext *cx, JSObject *global)
|
||||
js_InitStringClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(global->isGlobal());
|
||||
JS_ASSERT(global->isNative());
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
/*
|
||||
* Define escape/unescape, the URI encode/decode functions, and maybe
|
||||
* uneval on the global object.
|
||||
*/
|
||||
if (!JS_DefineFunctions(cx, global, string_functions))
|
||||
return NULL;
|
||||
GlobalObject *global = obj->asGlobal();
|
||||
|
||||
/* Create and initialize String.prototype. */
|
||||
JSObject *objectProto;
|
||||
if (!js_GetClassPrototype(cx, global, JSProto_Object, &objectProto))
|
||||
return NULL;
|
||||
|
||||
JSObject *proto = NewObject<WithProto::Class>(cx, &js_StringClass, objectProto, global);
|
||||
JSObject *proto = global->createBlankPrototype(cx, &js_StringClass);
|
||||
if (!proto || !proto->asString()->init(cx, cx->runtime->emptyString))
|
||||
return NULL;
|
||||
|
||||
@ -3214,21 +3203,17 @@ js_InitStringClass(JSContext *cx, JSObject *global)
|
||||
proto->brand(cx);
|
||||
ctor->brand(cx);
|
||||
|
||||
/*
|
||||
* Make sure proto's emptyShape is available to be shared by String
|
||||
* objects. JSObject::emptyShape is a one-slot cache. If we omit this, some
|
||||
* other class could snap it up. (The risk is particularly great for
|
||||
* Object.prototype.)
|
||||
*
|
||||
* All callers of JSObject::initSharingEmptyShape depend on this.
|
||||
*/
|
||||
if (!proto->getEmptyShape(cx, &js_StringClass, FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
|
||||
/* Install the fully-constructed String and String.prototype. */
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_String, ctor, proto))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Define escape/unescape, the URI encode/decode functions, and maybe
|
||||
* uneval on the global object.
|
||||
*/
|
||||
if (!JS_DefineFunctions(cx, global, string_functions))
|
||||
return NULL;
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
@ -202,4 +202,28 @@ GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx)
|
||||
return !v.isFalse();
|
||||
}
|
||||
|
||||
JSObject *
|
||||
GlobalObject::createBlankPrototype(JSContext *cx, Class *clasp)
|
||||
{
|
||||
JS_ASSERT(clasp != &js_ObjectClass);
|
||||
JS_ASSERT(clasp != &js_FunctionClass);
|
||||
|
||||
JSObject *objectProto;
|
||||
if (!js_GetClassPrototype(cx, this, JSProto_Object, &objectProto))
|
||||
return NULL;
|
||||
|
||||
JSObject *proto = NewNonFunction<WithProto::Given>(cx, clasp, objectProto, this);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Supply the created prototype object with an empty shape for the benefit
|
||||
* of callers of JSObject::initSharingEmptyShape.
|
||||
*/
|
||||
if (!proto->getEmptyShape(cx, clasp, gc::FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
@ -111,6 +111,16 @@ class GlobalObject : public ::JSObject {
|
||||
public:
|
||||
static GlobalObject *create(JSContext *cx, Class *clasp);
|
||||
|
||||
/*
|
||||
* Create an object to serve as [[Prototype]] for instances of the given
|
||||
* class, using |Object.prototype| as its [[Prototype]]. Users creating
|
||||
* prototype objects with particular internal structure (e.g. reserved
|
||||
* slots guaranteed to contain values of particular types) must immediately
|
||||
* complete the minimal initialization to make the returned object safe to
|
||||
* touch.
|
||||
*/
|
||||
JSObject *createBlankPrototype(JSContext *cx, js::Class *clasp);
|
||||
|
||||
void setThrowTypeError(JSFunction *fun) {
|
||||
Value &v = getSlotRef(THROWTYPEERROR);
|
||||
// Our bootstrapping code is currently too convoluted to correctly and
|
||||
|
Loading…
Reference in New Issue
Block a user