Bug 1805288 - Part 1: Add ChromeUtils.defineLazyGetter. r=smaug
Differential Revision: https://phabricator.services.mozilla.com/D171319
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include "ChromeUtils.h"
|
||||
|
||||
#include "JSOracleParent.h"
|
||||
#include "js/CallAndConstruct.h" // JS::Call
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/Object.h" // JS::GetClass
|
||||
#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById, JS::IdVector
|
||||
@@ -634,10 +635,11 @@ void ChromeUtils::ImportESModule(
|
||||
aRetval.set(moduleNamespace);
|
||||
}
|
||||
|
||||
namespace module_getter {
|
||||
namespace lazy_getter {
|
||||
|
||||
static const size_t SLOT_ID = 0;
|
||||
static const size_t SLOT_URI = 1;
|
||||
static const size_t SLOT_LAMBDA = 1;
|
||||
|
||||
static bool ExtractArgs(JSContext* aCx, JS::CallArgs& aArgs,
|
||||
JS::MutableHandle<JSObject*> aCallee,
|
||||
@@ -659,6 +661,56 @@ static bool ExtractArgs(JSContext* aCx, JS::CallArgs& aArgs,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool JSLazyGetter(JSContext* aCx, unsigned aArgc, JS::Value* aVp) {
|
||||
JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
|
||||
|
||||
JS::Rooted<JSObject*> callee(aCx);
|
||||
JS::Rooted<JSObject*> thisObj(aCx);
|
||||
JS::Rooted<jsid> id(aCx);
|
||||
if (!ExtractArgs(aCx, args, &callee, &thisObj, &id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> lambda(
|
||||
aCx, js::GetFunctionNativeReserved(callee, SLOT_LAMBDA));
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!JS::Call(aCx, thisObj, lambda, JS::HandleValueArray::empty(), &value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_DefinePropertyById(aCx, thisObj, id, value, JSPROP_ENUMERATE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().set(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool DefineLazyGetter(JSContext* aCx, JS::Handle<JSObject*> aTarget,
|
||||
JS::Handle<JS::Value> aName,
|
||||
JS::Handle<JSObject*> aLambda) {
|
||||
JS::Rooted<jsid> id(aCx);
|
||||
if (!JS_ValueToId(aCx, aName, &id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> getter(
|
||||
aCx, JS_GetFunctionObject(
|
||||
js::NewFunctionByIdWithReserved(aCx, JSLazyGetter, 0, 0, id)));
|
||||
if (!getter) {
|
||||
JS_ReportOutOfMemory(aCx);
|
||||
return false;
|
||||
}
|
||||
|
||||
js::SetFunctionNativeReserved(getter, SLOT_ID, aName);
|
||||
|
||||
JS::Rooted<JS::Value> lambdaValue(aCx, JS::ObjectValue(*aLambda));
|
||||
js::SetFunctionNativeReserved(getter, SLOT_LAMBDA, lambdaValue);
|
||||
|
||||
return JS_DefinePropertyById(aCx, aTarget, id, getter, nullptr,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
enum class ModuleType { JSM, ESM };
|
||||
|
||||
static bool ModuleGetterImpl(JSContext* aCx, unsigned aArgc, JS::Value* aVp,
|
||||
@@ -820,7 +872,21 @@ static bool DefineESModuleGetter(JSContext* aCx, JS::Handle<JSObject*> aTarget,
|
||||
return JS_DefinePropertyById(aCx, aTarget, aId, getter, setter,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
} // namespace module_getter
|
||||
|
||||
} // namespace lazy_getter
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::DefineLazyGetter(const GlobalObject& aGlobal,
|
||||
JS::Handle<JSObject*> aTarget,
|
||||
JS::Handle<JS::Value> aName,
|
||||
JS::Handle<JSObject*> aLambda,
|
||||
ErrorResult& aRv) {
|
||||
JSContext* cx = aGlobal.Context();
|
||||
if (!lazy_getter::DefineLazyGetter(cx, aTarget, aName, aLambda)) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::DefineModuleGetter(const GlobalObject& global,
|
||||
@@ -828,8 +894,8 @@ void ChromeUtils::DefineModuleGetter(const GlobalObject& global,
|
||||
const nsAString& id,
|
||||
const nsAString& resourceURI,
|
||||
ErrorResult& aRv) {
|
||||
if (!module_getter::DefineJSModuleGetter(global.Context(), target, id,
|
||||
resourceURI)) {
|
||||
if (!lazy_getter::DefineJSModuleGetter(global.Context(), target, id,
|
||||
resourceURI)) {
|
||||
aRv.NoteJSContextException(global.Context());
|
||||
}
|
||||
}
|
||||
@@ -839,7 +905,7 @@ void ChromeUtils::DefineESModuleGetters(const GlobalObject& global,
|
||||
JS::Handle<JSObject*> target,
|
||||
JS::Handle<JSObject*> modules,
|
||||
ErrorResult& aRv) {
|
||||
auto cx = global.Context();
|
||||
JSContext* cx = global.Context();
|
||||
|
||||
JS::Rooted<JS::IdVector> props(cx, JS::IdVector(cx));
|
||||
if (!JS_Enumerate(cx, modules, &props)) {
|
||||
@@ -862,8 +928,7 @@ void ChromeUtils::DefineESModuleGetters(const GlobalObject& global,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!module_getter::DefineESModuleGetter(cx, target, prop,
|
||||
resourceURIVal)) {
|
||||
if (!lazy_getter::DefineESModuleGetter(cx, target, prop, resourceURIVal)) {
|
||||
aRv.NoteJSContextException(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user