mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 06:15:43 +00:00
Bug 1067459 - Only install a small subset of the standard builtins in the self-hosting global. r=jorendorff
This commit is contained in:
parent
5184091514
commit
276cd0a709
@ -2055,17 +2055,12 @@ js_InitIntlClass(JSContext *cx, HandleObject obj)
|
||||
if (!JS_DefineFunctions(cx, Intl, intl_static_methods))
|
||||
return nullptr;
|
||||
|
||||
// Skip initialization of the Intl constructors during initialization of the
|
||||
// self-hosting global as we may get here before self-hosted code is compiled,
|
||||
// and no core code refers to the Intl classes.
|
||||
if (!cx->runtime()->isSelfHostingGlobal(cx->global())) {
|
||||
if (!InitCollatorClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
if (!InitNumberFormatClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
if (!InitDateTimeFormatClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
}
|
||||
if (!InitCollatorClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
if (!InitNumberFormatClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
if (!InitDateTimeFormatClass(cx, Intl, global))
|
||||
return nullptr;
|
||||
|
||||
global->setConstructor(JSProto_Intl, ObjectValue(*Intl));
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ function InitializeCollator(collator, locales, options) {
|
||||
// Step 13, unrolled.
|
||||
var numericValue = GetOption(options, "numeric", "boolean", undefined, undefined);
|
||||
if (numericValue !== undefined)
|
||||
numericValue = callFunction(std_Boolean_toString, numericValue);
|
||||
numericValue = numericValue ? 'true' : 'false';
|
||||
opt.kn = numericValue;
|
||||
|
||||
var caseFirstValue = GetOption(options, "caseFirst", "string", ["upper", "lower", "false"], undefined);
|
||||
|
@ -849,6 +849,7 @@ class MapIteratorObject : public JSObject
|
||||
static const JSFunctionSpec methods[];
|
||||
static MapIteratorObject *create(JSContext *cx, HandleObject mapobj, ValueMap *data,
|
||||
MapObject::IteratorKind kind);
|
||||
static bool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
|
||||
private:
|
||||
@ -856,7 +857,6 @@ class MapIteratorObject : public JSObject
|
||||
inline ValueMap::Range *range();
|
||||
inline MapObject::IteratorKind kind() const;
|
||||
static bool next_impl(JSContext *cx, CallArgs args);
|
||||
static bool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
@ -1157,7 +1157,8 @@ WriteBarrierPost(JSRuntime *rt, ValueSet *set, const Value &key)
|
||||
}
|
||||
|
||||
bool
|
||||
MapObject::entries(JSContext *cx, HandleObject obj, JS::AutoValueVector *entries)
|
||||
MapObject::getKeysAndValuesInterleaved(JSContext *cx, HandleObject obj,
|
||||
JS::AutoValueVector *entries)
|
||||
{
|
||||
ValueMap *map = obj->as<MapObject>().getData();
|
||||
if (!map)
|
||||
@ -1497,6 +1498,7 @@ class SetIteratorObject : public JSObject
|
||||
static const JSFunctionSpec methods[];
|
||||
static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data,
|
||||
SetObject::IteratorKind kind);
|
||||
static bool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
static void finalize(FreeOp *fop, JSObject *obj);
|
||||
|
||||
private:
|
||||
@ -1504,7 +1506,6 @@ class SetIteratorObject : public JSObject
|
||||
inline ValueSet::Range *range();
|
||||
inline SetObject::IteratorKind kind() const;
|
||||
static bool next_impl(JSContext *cx, CallArgs args);
|
||||
static bool next(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
} /* anonymous namespace */
|
||||
@ -1966,3 +1967,15 @@ js_InitSetClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return SetObject::initClass(cx, obj);
|
||||
}
|
||||
|
||||
const JSFunctionSpec selfhosting_collection_iterator_methods[] = {
|
||||
JS_FN("std_Map_iterator_next", MapIteratorObject::next, 0, 0),
|
||||
JS_FN("std_Set_iterator_next", SetIteratorObject::next, 0, 0),
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
bool
|
||||
js::InitSelfHostingCollectionIteratorFunctions(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return JS_DefineFunctions(cx, obj, selfhosting_collection_iterator_methods);
|
||||
}
|
||||
|
@ -92,9 +92,11 @@ class MapObject : public JSObject {
|
||||
static JSObject *initClass(JSContext *cx, JSObject *obj);
|
||||
static const Class class_;
|
||||
|
||||
// Entries is every key followed by value.
|
||||
static bool entries(JSContext *cx, HandleObject obj, JS::AutoValueVector *entries);
|
||||
static bool getKeysAndValuesInterleaved(JSContext *cx, HandleObject obj,
|
||||
JS::AutoValueVector *entries);
|
||||
static bool entries(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool set(JSContext *cx, HandleObject obj, HandleValue key, HandleValue value);
|
||||
static bool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static MapObject* create(JSContext *cx);
|
||||
|
||||
private:
|
||||
@ -115,7 +117,6 @@ class MapObject : public JSObject {
|
||||
static bool get_impl(JSContext *cx, CallArgs args);
|
||||
static bool get(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool has_impl(JSContext *cx, CallArgs args);
|
||||
static bool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool set_impl(JSContext *cx, CallArgs args);
|
||||
static bool set(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool delete_impl(JSContext *cx, CallArgs args);
|
||||
@ -125,7 +126,6 @@ class MapObject : public JSObject {
|
||||
static bool values_impl(JSContext *cx, CallArgs args);
|
||||
static bool values(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool entries_impl(JSContext *cx, CallArgs args);
|
||||
static bool entries(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool clear_impl(JSContext *cx, CallArgs args);
|
||||
static bool clear(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
@ -137,7 +137,9 @@ class SetObject : public JSObject {
|
||||
static const Class class_;
|
||||
|
||||
static bool keys(JSContext *cx, HandleObject obj, JS::AutoValueVector *keys);
|
||||
static bool values(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool add(JSContext *cx, HandleObject obj, HandleValue key);
|
||||
static bool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static SetObject* create(JSContext *cx);
|
||||
|
||||
private:
|
||||
@ -156,19 +158,20 @@ class SetObject : public JSObject {
|
||||
static bool size_impl(JSContext *cx, CallArgs args);
|
||||
static bool size(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool has_impl(JSContext *cx, CallArgs args);
|
||||
static bool has(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool add_impl(JSContext *cx, CallArgs args);
|
||||
static bool add(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool delete_impl(JSContext *cx, CallArgs args);
|
||||
static bool delete_(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool values_impl(JSContext *cx, CallArgs args);
|
||||
static bool values(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool entries_impl(JSContext *cx, CallArgs args);
|
||||
static bool entries(JSContext *cx, unsigned argc, Value *vp);
|
||||
static bool clear_impl(JSContext *cx, CallArgs args);
|
||||
static bool clear(JSContext *cx, unsigned argc, Value *vp);
|
||||
};
|
||||
|
||||
extern bool
|
||||
InitSelfHostingCollectionIteratorFunctions(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
|
@ -532,8 +532,8 @@ obj_lookupSetter(JSContext *cx, unsigned argc, Value *vp)
|
||||
#endif /* JS_OLD_GETTER_SETTER_METHODS */
|
||||
|
||||
/* ES5 15.2.3.2. */
|
||||
static bool
|
||||
obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_getPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -703,8 +703,8 @@ obj_unwatch(JSContext *cx, unsigned argc, Value *vp)
|
||||
#endif /* JS_HAS_OBJ_WATCHPOINT */
|
||||
|
||||
/* ECMA 15.2.4.5. */
|
||||
static bool
|
||||
obj_hasOwnProperty(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_hasOwnProperty(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -778,8 +778,8 @@ obj_isPrototypeOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
}
|
||||
|
||||
/* ES5 15.2.3.5: Object.create(O [, Properties]) */
|
||||
static bool
|
||||
obj_create(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_create(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (args.length() == 0) {
|
||||
@ -826,8 +826,8 @@ obj_create(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject obj(cx);
|
||||
@ -951,8 +951,8 @@ GetOwnPropertyKeys(JSContext *cx, const JS::CallArgs &args, unsigned flags)
|
||||
|
||||
} // namespace js
|
||||
|
||||
static bool
|
||||
obj_getOwnPropertyNames(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::obj_getOwnPropertyNames(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return GetOwnPropertyKeys(cx, args, JSITER_OWNONLY | JSITER_HIDDEN);
|
||||
|
@ -28,6 +28,22 @@ obj_construct(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
bool
|
||||
obj_valueOf(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
// Object methods exposed so they can be installed in the self-hosting global.
|
||||
bool
|
||||
obj_create(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
bool
|
||||
obj_getOwnPropertyNames(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
bool
|
||||
obj_getOwnPropertyDescriptor(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
bool
|
||||
obj_getPrototypeOf(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
bool
|
||||
obj_hasOwnProperty(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
// Exposed so SelfHosting.cpp can use it in the OwnPropertyKeys intrinsic
|
||||
bool
|
||||
GetOwnPropertyKeys(JSContext *cx, const JS::CallArgs &args, unsigned flags);
|
||||
|
@ -25,71 +25,18 @@
|
||||
|
||||
#include "SelfHostingDefines.h"
|
||||
|
||||
// Remove unsafe builtin functions.
|
||||
Object.defineProperty = null; // See bug 988416.
|
||||
|
||||
// Cache builtin functions so using them doesn't require cloning the whole object they're
|
||||
// installed on.
|
||||
// All C++-implemented standard builtins library functions used in self-hosted
|
||||
// code are installed via the std_functions JSFunctionSpec[] in
|
||||
// SelfHosting.cpp.
|
||||
//
|
||||
// WARNING: Do not make std_ references to builtin constructors (like Array and
|
||||
// Object) below. Setting `var std_Array = Array;`, for instance, would cause
|
||||
// the entire Array constructor, including its prototype and methods, to be
|
||||
// cloned into content compartments.
|
||||
var std_Array_indexOf = ArrayIndexOf;
|
||||
var std_Array_iterator = Array.prototype.iterator;
|
||||
var std_Array_join = Array.prototype.join;
|
||||
var std_Array_push = Array.prototype.push;
|
||||
var std_Array_pop = Array.prototype.pop;
|
||||
var std_Array_shift = Array.prototype.shift;
|
||||
var std_Array_slice = Array.prototype.slice;
|
||||
var std_Array_sort = Array.prototype.sort;
|
||||
var std_Array_unshift = Array.prototype.unshift;
|
||||
var std_Boolean_toString = Boolean.prototype.toString;
|
||||
var Std_Date = Date;
|
||||
var std_Date_now = Date.now;
|
||||
var std_Date_valueOf = Date.prototype.valueOf;
|
||||
var std_Function_bind = Function.prototype.bind;
|
||||
var std_Function_apply = Function.prototype.apply;
|
||||
var std_Math_floor = Math.floor;
|
||||
var std_Math_max = Math.max;
|
||||
var std_Math_min = Math.min;
|
||||
var std_Math_abs = Math.abs;
|
||||
var std_Math_imul = Math.imul;
|
||||
var std_Math_log2 = Math.log2;
|
||||
var std_Number_valueOf = Number.prototype.valueOf;
|
||||
var std_Number_POSITIVE_INFINITY = Number.POSITIVE_INFINITY;
|
||||
var std_Object_create = Object.create;
|
||||
var std_Object_getOwnPropertyNames = Object.getOwnPropertyNames;
|
||||
var std_Object_hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var std_Object_getPrototypeOf = Object.getPrototypeOf;
|
||||
var std_Object_getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
|
||||
var std_RegExp_test = RegExp.prototype.test;
|
||||
var std_String_fromCharCode = String.fromCharCode;
|
||||
var std_String_charCodeAt = String.prototype.charCodeAt;
|
||||
var std_String_indexOf = String.prototype.indexOf;
|
||||
var std_String_lastIndexOf = String.prototype.lastIndexOf;
|
||||
var std_String_match = String.prototype.match;
|
||||
var std_String_replace = String.prototype.replace;
|
||||
var std_String_split = String.prototype.split;
|
||||
var std_String_startsWith = String.prototype.startsWith;
|
||||
var std_String_substring = String.prototype.substring;
|
||||
var std_String_toLowerCase = String.prototype.toLowerCase;
|
||||
var std_String_toUpperCase = String.prototype.toUpperCase;
|
||||
var std_WeakMap = WeakMap;
|
||||
var std_WeakMap_get = WeakMap.prototype.get;
|
||||
var std_WeakMap_has = WeakMap.prototype.has;
|
||||
var std_WeakMap_set = WeakMap.prototype.set;
|
||||
var std_WeakMap_clear = WeakMap.prototype.clear;
|
||||
var std_WeakMap_delete = WeakMap.prototype.delete;
|
||||
var std_Map_has = Map.prototype.has;
|
||||
var std_Set_has = Set.prototype.has;
|
||||
// The few items below here are either self-hosted or installing them under a
|
||||
// std_Foo name would require ugly contortions, so they just get aliased here.
|
||||
var std_iterator = '@@iterator'; // FIXME: Change to be a symbol.
|
||||
var std_Array_indexOf = ArrayIndexOf;
|
||||
// WeakMap is a bare constructor without properties or methods.
|
||||
var std_WeakMap = WeakMap;
|
||||
// StopIteration is a bare constructor without properties or methods.
|
||||
var std_StopIteration = StopIteration;
|
||||
var std_Map_iterator = Map.prototype[std_iterator];
|
||||
var std_Set_iterator = Set.prototype[std_iterator];
|
||||
var std_Map_iterator_next = Object.getPrototypeOf(Map()[std_iterator]()).next;
|
||||
var std_Set_iterator_next = Object.getPrototypeOf(Set()[std_iterator]()).next;
|
||||
|
||||
|
||||
|
||||
/********** List specification type **********/
|
||||
|
@ -3278,15 +3278,6 @@ JS_DefineProperties(JSContext *cx, HandleObject obj, const JSPropertySpec *ps)
|
||||
// native one.
|
||||
JS_ASSERT(!ps->getter.propertyOp.op && !ps->setter.propertyOp.op);
|
||||
JS_ASSERT(ps->flags & JSPROP_GETTER);
|
||||
/*
|
||||
* During creation of the self-hosting global, we ignore all
|
||||
* self-hosted properties, as that means we're currently setting up
|
||||
* the global object that the self-hosted code is then compiled
|
||||
* in. That means that Self-hosted properties can't be used in the
|
||||
* self-hosting global itself, right now.
|
||||
*/
|
||||
if (cx->runtime()->isSelfHostingGlobal(cx->global()))
|
||||
continue;
|
||||
|
||||
ok = DefineSelfHostedProperty(cx, obj, ps->name,
|
||||
ps->getter.selfHosted.funname,
|
||||
@ -4129,15 +4120,6 @@ JS_DefineFunctions(JSContext *cx, HandleObject obj, const JSFunctionSpec *fs)
|
||||
if (fs->selfHostedName) {
|
||||
JS_ASSERT(!fs->call.op);
|
||||
JS_ASSERT(!fs->call.info);
|
||||
/*
|
||||
* During creation of the self-hosting global, we ignore all
|
||||
* self-hosted functions, as that means we're currently setting up
|
||||
* the global object that the self-hosted code is then compiled
|
||||
* in. Self-hosted functions can access each other via their names,
|
||||
* but not via the builtin classes they get installed into.
|
||||
*/
|
||||
if (cx->runtime()->isSelfHostingGlobal(cx->global()))
|
||||
continue;
|
||||
|
||||
RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName)));
|
||||
if (!shName)
|
||||
|
@ -2246,8 +2246,8 @@ js::array_shift(JSContext *cx, unsigned argc, Value *vp)
|
||||
return SetLengthProperty(cx, obj, newlen);
|
||||
}
|
||||
|
||||
static bool
|
||||
array_unshift(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::array_unshift(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedObject obj(cx, ToObject(cx, args.thisv()));
|
||||
@ -2702,8 +2702,8 @@ js::array_concat(JSContext *cx, unsigned argc, Value *vp)
|
||||
return SetLengthProperty(cx, narr, length);
|
||||
}
|
||||
|
||||
static bool
|
||||
array_slice(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::array_slice(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -2981,7 +2981,7 @@ static const JSFunctionSpec array_methods[] = {
|
||||
JS_FN(js_toLocaleString_str,array_toLocaleString,0,0),
|
||||
|
||||
/* Perl-ish methods. */
|
||||
JS_FN("join", js::array_join, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("join", array_join, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("reverse", array_reverse, 0,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("sort", array_sort, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("push", array_push, 1,JSFUN_GENERIC_NATIVE),
|
||||
|
@ -179,6 +179,12 @@ ArrayShiftMoveElements(JSObject *obj);
|
||||
extern bool
|
||||
array_shift(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
extern bool
|
||||
array_unshift(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
extern bool
|
||||
array_slice(JSContext *cx, unsigned argc, js::Value *vp);
|
||||
|
||||
/*
|
||||
* Append the given (non-hole) value to the end of an array. The array must be
|
||||
* a newborn array -- that is, one which has not been exposed to script for
|
||||
|
@ -1195,8 +1195,8 @@ NowAsMillis()
|
||||
return (double) (PRMJ_Now() / PRMJ_USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static bool
|
||||
date_now(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::date_now(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
args.rval().setDouble(NowAsMillis());
|
||||
@ -2863,8 +2863,8 @@ date_valueOf_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
date_valueOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::date_valueOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsDate, date_valueOf_impl>(cx, args);
|
||||
|
@ -60,4 +60,15 @@ js_DateGetSeconds(JSObject *obj);
|
||||
bool
|
||||
js_Date(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
namespace js {
|
||||
|
||||
/* Date methods exposed so they can be installed in the self-hosting global. */
|
||||
bool
|
||||
date_now(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
bool
|
||||
date_valueOf(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jsdate_h */
|
||||
|
@ -1582,8 +1582,8 @@ fun_isGenerator(JSContext *cx, unsigned argc, Value *vp)
|
||||
}
|
||||
|
||||
/* ES5 15.3.4.5. */
|
||||
static bool
|
||||
fun_bind(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::fun_bind(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
|
@ -536,6 +536,9 @@ fun_resolve(JSContext *cx, HandleObject obj, HandleId id, MutableHandleObject ob
|
||||
extern bool
|
||||
fun_toString(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
fun_bind(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
/*
|
||||
* Function extended with reserved slots for use by various kinds of functions.
|
||||
* Most functions do not have these extensions, but enough do that efficient
|
||||
|
@ -2099,17 +2099,24 @@ GlobalObject::initIteratorClasses(JSContext *cx, Handle<GlobalObject *> global)
|
||||
global->setPrototype(JSProto_GeneratorFunction, ObjectValue(*genFunctionProto));
|
||||
}
|
||||
|
||||
if (global->getPrototype(JSProto_StopIteration).isUndefined()) {
|
||||
proto = global->createBlankPrototype(cx, &StopIterationObject::class_);
|
||||
if (!proto || !JSObject::freeze(cx, proto))
|
||||
return false;
|
||||
return GlobalObject::initStopIterationClass(cx, global);
|
||||
}
|
||||
|
||||
// This should use a non-JSProtoKey'd slot, but this is easier for now.
|
||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_StopIteration, proto, proto))
|
||||
return false;
|
||||
/* static */ bool
|
||||
GlobalObject::initStopIterationClass(JSContext *cx, Handle<GlobalObject *> global)
|
||||
{
|
||||
if (!global->getPrototype(JSProto_StopIteration).isUndefined())
|
||||
return true;
|
||||
|
||||
global->setConstructor(JSProto_StopIteration, ObjectValue(*proto));
|
||||
}
|
||||
RootedObject proto(cx, global->createBlankPrototype(cx, &StopIterationObject::class_));
|
||||
if (!proto || !JSObject::freeze(cx, proto))
|
||||
return false;
|
||||
|
||||
// This should use a non-JSProtoKey'd slot, but this is easier for now.
|
||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_StopIteration, proto, proto))
|
||||
return false;
|
||||
|
||||
global->setConstructor(JSProto_StopIteration, ObjectValue(*proto));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -136,7 +136,8 @@ FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject pro
|
||||
self->setOriginalEval(evalobj);
|
||||
|
||||
RootedObject intrinsicsHolder(cx);
|
||||
if (cx->runtime()->isSelfHostingGlobal(self)) {
|
||||
bool isSelfHostingGlobal = cx->runtime()->isSelfHostingGlobal(self);
|
||||
if (isSelfHostingGlobal) {
|
||||
intrinsicsHolder = self;
|
||||
} else {
|
||||
intrinsicsHolder = NewObjectWithGivenProto(cx, &JSObject::class_, proto, self,
|
||||
@ -158,8 +159,10 @@ FinishObjectClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject pro
|
||||
* Define self-hosted functions after setting the intrinsics holder
|
||||
* (which is needed to define self-hosted functions)
|
||||
*/
|
||||
if (!JS_DefineFunctions(cx, ctor, object_static_selfhosted_methods))
|
||||
return false;
|
||||
if (!isSelfHostingGlobal) {
|
||||
if (!JS_DefineFunctions(cx, ctor, object_static_selfhosted_methods))
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The global object should have |Object.prototype| as its [[Prototype]].
|
||||
|
@ -627,8 +627,8 @@ DoSubstr(JSContext *cx, JSString *str, size_t begin, size_t len)
|
||||
return NewDependentString(cx, str, begin, len);
|
||||
}
|
||||
|
||||
static bool
|
||||
str_substring(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_substring(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -755,8 +755,8 @@ ToLowerCaseHelper(JSContext *cx, CallReceiver call)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
str_toLowerCase(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_toLowerCase(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return ToLowerCaseHelper(cx, CallArgsFromVp(argc, vp));
|
||||
}
|
||||
@ -906,8 +906,8 @@ ToUpperCaseHelper(JSContext *cx, CallReceiver call)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
str_toUpperCase(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_toUpperCase(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
return ToUpperCaseHelper(cx, CallArgsFromVp(argc, vp));
|
||||
}
|
||||
@ -1653,8 +1653,8 @@ str_contains(JSContext *cx, unsigned argc, Value *vp)
|
||||
}
|
||||
|
||||
/* ES6 20120927 draft 15.5.4.7. */
|
||||
static bool
|
||||
str_indexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_indexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
@ -1726,8 +1726,8 @@ LastIndexOfImpl(const TextChar *text, size_t textLen, const PatChar *pat, size_t
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool
|
||||
str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedString textstr(cx, ThisToStringForStringProto(cx, args));
|
||||
@ -1820,8 +1820,8 @@ HasSubstringAt(JSLinearString *text, JSLinearString *pat, size_t start)
|
||||
}
|
||||
|
||||
/* ES6 20131108 draft 21.1.3.18. */
|
||||
static bool
|
||||
str_startsWith(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::str_startsWith(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
|
@ -300,6 +300,26 @@ str_fromCharCode(JSContext *cx, unsigned argc, Value *vp);
|
||||
extern bool
|
||||
str_fromCharCode_one_arg(JSContext *cx, HandleValue code, MutableHandleValue rval);
|
||||
|
||||
/* String methods exposed so they can be installed in the self-hosting global. */
|
||||
|
||||
extern bool
|
||||
str_indexOf(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
str_lastIndexOf(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
str_startsWith(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
str_substring(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
str_toLowerCase(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
str_toUpperCase(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern bool
|
||||
|
@ -238,8 +238,8 @@ WeakMap_has_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WeakMap_has(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::WeakMap_has(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsWeakMap, WeakMap_has_impl>(cx, args);
|
||||
@ -259,8 +259,8 @@ WeakMap_clear_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WeakMap_clear(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::WeakMap_clear(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsWeakMap, WeakMap_clear_impl>(cx, args);
|
||||
@ -291,8 +291,8 @@ WeakMap_get_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WeakMap_get(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::WeakMap_get(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsWeakMap, WeakMap_get_impl>(cx, args);
|
||||
@ -324,8 +324,8 @@ WeakMap_delete_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WeakMap_delete(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::WeakMap_delete(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsWeakMap, WeakMap_delete_impl>(cx, args);
|
||||
@ -433,8 +433,8 @@ WeakMap_set_impl(JSContext *cx, CallArgs args)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
WeakMap_set(JSContext *cx, unsigned argc, Value *vp)
|
||||
bool
|
||||
js::WeakMap_set(JSContext *cx, unsigned argc, Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
return CallNonGenericMethod<IsWeakMap, WeakMap_set_impl>(cx, args);
|
||||
@ -570,8 +570,8 @@ static const JSFunctionSpec weak_map_methods[] = {
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
JSObject *
|
||||
js_InitWeakMapClass(JSContext *cx, HandleObject obj)
|
||||
static JSObject *
|
||||
InitWeakMapClass(JSContext *cx, HandleObject obj, bool defineMembers)
|
||||
{
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
@ -589,11 +589,25 @@ js_InitWeakMapClass(JSContext *cx, HandleObject obj)
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, weakMapProto))
|
||||
return nullptr;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, weakMapProto, nullptr, weak_map_methods))
|
||||
return nullptr;
|
||||
if (defineMembers) {
|
||||
if (!DefinePropertiesAndFunctions(cx, weakMapProto, nullptr, weak_map_methods))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_WeakMap, ctor, weakMapProto))
|
||||
return nullptr;
|
||||
return weakMapProto;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_InitWeakMapClass(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return InitWeakMapClass(cx, obj, true);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js::InitBareWeakMapCtor(JSContext *cx, HandleObject obj)
|
||||
{
|
||||
return InitWeakMapClass(cx, obj, false);
|
||||
}
|
||||
|
||||
|
@ -279,6 +279,26 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/* WeakMap methods exposed so they can be installed in the self-hosting global. */
|
||||
|
||||
extern JSObject *
|
||||
InitBareWeakMapCtor(JSContext *cx, js::HandleObject obj);
|
||||
|
||||
extern bool
|
||||
WeakMap_has(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
WeakMap_get(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
WeakMap_set(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
WeakMap_delete(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
extern bool
|
||||
WeakMap_clear(JSContext *cx, unsigned argc, Value *vp);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern JSObject *
|
||||
|
@ -284,6 +284,57 @@ GlobalObject::initStandardClasses(JSContext *cx, Handle<GlobalObject*> global)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a builtin constructor and its prototype without defining any
|
||||
* properties or functions on it.
|
||||
*
|
||||
* Used in self-hosting to install the few builtin constructors required by
|
||||
* self-hosted builtins.
|
||||
*/
|
||||
static bool
|
||||
InitBareBuiltinCtor(JSContext *cx, Handle<GlobalObject*> global, JSProtoKey protoKey)
|
||||
{
|
||||
MOZ_ASSERT(cx->runtime()->isSelfHostingGlobal(global));
|
||||
const Class *clasp = ProtoKeyToClass(protoKey);
|
||||
RootedObject proto(cx);
|
||||
proto = clasp->spec.createPrototype(cx, protoKey);
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
RootedObject ctor(cx, clasp->spec.createConstructor(cx, protoKey));
|
||||
if (!ctor)
|
||||
return false;
|
||||
|
||||
return GlobalObject::initBuiltinConstructor(cx, global, protoKey, ctor, proto);
|
||||
}
|
||||
|
||||
/**
|
||||
* The self-hosting global only gets a small subset of all standard classes.
|
||||
* Even those are only created as bare constructors without any properties
|
||||
* or functions.
|
||||
*/
|
||||
/* static */ bool
|
||||
GlobalObject::initSelfHostingBuiltins(JSContext *cx, Handle<GlobalObject*> global,
|
||||
const JSFunctionSpec *builtins)
|
||||
{
|
||||
/* Define a top-level property 'undefined' with the undefined value. */
|
||||
if (!JSObject::defineProperty(cx, global, cx->names().undefined, UndefinedHandleValue,
|
||||
JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return InitBareBuiltinCtor(cx, global, JSProto_Array) &&
|
||||
InitBareBuiltinCtor(cx, global, JSProto_TypedArray) &&
|
||||
InitBareBuiltinCtor(cx, global, JSProto_Uint8Array) &&
|
||||
InitBareBuiltinCtor(cx, global, JSProto_Uint32Array) &&
|
||||
InitBareWeakMapCtor(cx, global) &&
|
||||
initStopIterationClass(cx, global) &&
|
||||
InitSelfHostingCollectionIteratorFunctions(cx, global) &&
|
||||
JS_DefineFunctions(cx, global, builtins);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
|
@ -611,6 +611,7 @@ class GlobalObject : public JSObject
|
||||
|
||||
// Implemented in jsiter.cpp.
|
||||
static bool initIteratorClasses(JSContext *cx, Handle<GlobalObject*> global);
|
||||
static bool initStopIterationClass(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/MapObject.cpp.
|
||||
static bool initMapIteratorProto(JSContext *cx, Handle<GlobalObject*> global);
|
||||
@ -626,6 +627,8 @@ class GlobalObject : public JSObject
|
||||
static bool initTypedObjectModule(JSContext *cx, Handle<GlobalObject*> global);
|
||||
|
||||
static bool initStandardClasses(JSContext *cx, Handle<GlobalObject*> global);
|
||||
static bool initSelfHostingBuiltins(JSContext *cx, Handle<GlobalObject*> global,
|
||||
const JSFunctionSpec *builtins);
|
||||
|
||||
typedef js::Vector<js::Debugger *, 0, js::SystemAllocPolicy> DebuggerVector;
|
||||
|
||||
|
@ -8,9 +8,11 @@
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jsdate.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "jshashutil.h"
|
||||
#include "jsobj.h"
|
||||
#include "jsweakmap.h"
|
||||
#include "jswrapper.h"
|
||||
#include "selfhosted.out.h"
|
||||
|
||||
@ -803,7 +805,72 @@ js::intrinsic_IsConstructing(JSContext *cx, unsigned argc, Value *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
// The self-hosting global isn't initialized with the normal set of builtins.
|
||||
// Instead, individual C++-implemented functions that're required by
|
||||
// self-hosted code are defined as global functions. Accessing these
|
||||
// functions via a content compartment's builtins would be unsafe, because
|
||||
// content script might have changed the builtins' prototypes' members.
|
||||
// Installing the whole set of builtins in the self-hosting compartment, OTOH,
|
||||
// would be wasteful: it increases memory usage and initialization time for
|
||||
// self-hosting compartment.
|
||||
//
|
||||
// Additionally, a set of C++-implemented helper functions is defined on the
|
||||
// self-hosting global.
|
||||
static const JSFunctionSpec intrinsic_functions[] = {
|
||||
JS_FN("std_Array_join", array_join, 1,0),
|
||||
JS_FN("std_Array_push", array_push, 1,0),
|
||||
JS_FN("std_Array_pop", array_pop, 0,0),
|
||||
JS_FN("std_Array_shift", array_shift, 0,0),
|
||||
JS_FN("std_Array_unshift", array_unshift, 1,0),
|
||||
JS_FN("std_Array_slice", array_slice, 2,0),
|
||||
JS_FN("std_Array_sort", array_sort, 1,0),
|
||||
|
||||
JS_FN("std_Date_now", date_now, 0,0),
|
||||
JS_FN("std_Date_valueOf", date_valueOf, 0,0),
|
||||
|
||||
JS_FN("std_Function_bind", fun_bind, 1,0),
|
||||
JS_FN("std_Function_apply", js_fun_apply, 1,0),
|
||||
|
||||
JS_FN("std_Math_floor", math_floor, 1,0),
|
||||
JS_FN("std_Math_max", math_max, 2,0),
|
||||
JS_FN("std_Math_min", math_min, 2,0),
|
||||
JS_FN("std_Math_abs", math_abs, 1,0),
|
||||
JS_FN("std_Math_imul", math_imul, 2,0),
|
||||
JS_FN("std_Math_log2", math_log2, 1,0),
|
||||
|
||||
JS_FN("std_Map_has", MapObject::has, 1,0),
|
||||
JS_FN("std_Map_iterator", MapObject::entries, 0,0),
|
||||
|
||||
JS_FN("std_Number_valueOf", js_num_valueOf, 0,0),
|
||||
|
||||
JS_FN("std_Object_create", obj_create, 2,0),
|
||||
JS_FN("std_Object_getPrototypeOf", obj_getPrototypeOf, 1,0),
|
||||
JS_FN("std_Object_getOwnPropertyNames", obj_getOwnPropertyNames, 1,0),
|
||||
JS_FN("std_Object_getOwnPropertyDescriptor", obj_getOwnPropertyDescriptor, 2,0),
|
||||
JS_FN("std_Object_hasOwnProperty", obj_hasOwnProperty, 2,0),
|
||||
|
||||
JS_FN("std_Set_has", SetObject::has, 1,0),
|
||||
JS_FN("std_Set_iterator", SetObject::values, 0,0),
|
||||
|
||||
JS_FN("std_String_fromCharCode", str_fromCharCode, 1,0),
|
||||
JS_FN("std_String_charCodeAt", js_str_charCodeAt, 1,0),
|
||||
JS_FN("std_String_indexOf", str_indexOf, 1,0),
|
||||
JS_FN("std_String_lastIndexOf", str_lastIndexOf, 1,0),
|
||||
JS_FN("std_String_match", str_match, 1,0),
|
||||
JS_FN("std_String_replace", str_replace, 2,0),
|
||||
JS_FN("std_String_split", str_split, 2,0),
|
||||
JS_FN("std_String_startsWith", str_startsWith, 2,0),
|
||||
JS_FN("std_String_substring", str_substring, 2,0),
|
||||
JS_FN("std_String_toLowerCase", str_toLowerCase, 0,0),
|
||||
JS_FN("std_String_toUpperCase", str_toUpperCase, 0,0),
|
||||
|
||||
JS_FN("std_WeakMap_has", WeakMap_has, 1,0),
|
||||
JS_FN("std_WeakMap_get", WeakMap_get, 2,0),
|
||||
JS_FN("std_WeakMap_set", WeakMap_set, 2,0),
|
||||
JS_FN("std_WeakMap_delete", WeakMap_delete, 1,0),
|
||||
JS_FN("std_WeakMap_clear", WeakMap_clear, 0,0),
|
||||
|
||||
// Helper funtions after this point.
|
||||
JS_FN("ToObject", intrinsic_ToObject, 1,0),
|
||||
JS_FN("IsObject", intrinsic_IsObject, 1,0),
|
||||
JS_FN("ToInteger", intrinsic_ToInteger, 1,0),
|
||||
@ -1013,15 +1080,8 @@ JSRuntime::initSelfHosting(JSContext *cx)
|
||||
Rooted<GlobalObject*> shg(cx, &selfHostingGlobal_->as<GlobalObject>());
|
||||
selfHostingGlobal_->compartment()->isSelfHosting = true;
|
||||
selfHostingGlobal_->compartment()->isSystem = true;
|
||||
/*
|
||||
* During initialization of standard classes for the self-hosting global,
|
||||
* all self-hosted functions are ignored. Thus, we don't create cyclic
|
||||
* dependencies in the order of initialization.
|
||||
*/
|
||||
if (!GlobalObject::initStandardClasses(cx, shg))
|
||||
return false;
|
||||
|
||||
if (!JS_DefineFunctions(cx, shg, intrinsic_functions))
|
||||
if (!GlobalObject::initSelfHostingBuiltins(cx, shg, intrinsic_functions))
|
||||
return false;
|
||||
|
||||
JS_FireOnNewGlobalObject(cx, shg);
|
||||
|
@ -976,7 +976,7 @@ JSStructuredCloneWriter::traverseMap(HandleObject obj)
|
||||
RootedObject unwrapped(context(), CheckedUnwrap(obj));
|
||||
MOZ_ASSERT(unwrapped);
|
||||
JSAutoCompartment ac(context(), unwrapped);
|
||||
if (!MapObject::entries(context(), unwrapped, &newEntries))
|
||||
if (!MapObject::getKeysAndValuesInterleaved(context(), unwrapped, &newEntries))
|
||||
return false;
|
||||
}
|
||||
if (!context()->compartment()->wrap(context(), newEntries))
|
||||
|
Loading…
Reference in New Issue
Block a user