Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6b9d9cbea |
No files matched your search
@@ -58,9 +58,9 @@ ModuleScript::UnlinkModuleRecord()
|
||||
{
|
||||
// Remove module's back reference to this object request if present.
|
||||
if (mModuleRecord) {
|
||||
MOZ_ASSERT(JS::GetModulePrivate(mModuleRecord).toPrivate() ==
|
||||
MOZ_ASSERT(JS::GetModuleHostDefinedField(mModuleRecord).toPrivate() ==
|
||||
this);
|
||||
JS::SetModulePrivate(mModuleRecord, JS::UndefinedValue());
|
||||
JS::SetModuleHostDefinedField(mModuleRecord, JS::UndefinedValue());
|
||||
mModuleRecord = nullptr;
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ ModuleScript::SetModuleRecord(JS::Handle<JSObject*> aModuleRecord)
|
||||
|
||||
// Make module's host defined field point to this module script object.
|
||||
// This is cleared in the UnlinkModuleRecord().
|
||||
JS::SetModulePrivate(mModuleRecord, JS::PrivateValue(this));
|
||||
JS::SetModuleHostDefinedField(mModuleRecord, JS::PrivateValue(this));
|
||||
HoldJSObjects(this);
|
||||
}
|
||||
|
||||
|
||||
+41
-34
@@ -599,38 +599,31 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
|
||||
return rv;
|
||||
}
|
||||
|
||||
static bool
|
||||
CreateTypeError(JSContext* aCx, ModuleScript* aScript, const nsString& aMessage,
|
||||
JS::MutableHandle<JS::Value> aError)
|
||||
{
|
||||
JS::Rooted<JSObject*> module(aCx, aScript->ModuleRecord());
|
||||
JS::Rooted<JSScript*> script(aCx, JS::GetModuleScript(aCx, module));
|
||||
JS::Rooted<JSString*> filename(aCx);
|
||||
filename = JS_NewStringCopyZ(aCx, JS_GetScriptFilename(script));
|
||||
if (!filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> message(aCx, JS_NewUCStringCopyZ(aCx, aMessage.get()));
|
||||
if (!message) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, filename, 0, 0, nullptr,
|
||||
message, aError);
|
||||
}
|
||||
|
||||
static nsresult
|
||||
HandleResolveFailure(JSContext* aCx, ModuleScript* aScript,
|
||||
const nsAString& aSpecifier)
|
||||
const nsAString& aSpecifier,
|
||||
uint32_t aLineNumber, uint32_t aColumnNumber)
|
||||
{
|
||||
// TODO: How can we get the line number of the failed import?
|
||||
nsAutoCString url;
|
||||
aScript->BaseURL()->GetAsciiSpec(url);
|
||||
|
||||
JS::Rooted<JSString*> filename(aCx);
|
||||
filename = JS_NewStringCopyZ(aCx, url.get());
|
||||
if (!filename) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsAutoString message(NS_LITERAL_STRING("Error resolving module specifier: "));
|
||||
message.Append(aSpecifier);
|
||||
|
||||
JS::Rooted<JSString*> string(aCx, JS_NewUCStringCopyZ(aCx, message.get()));
|
||||
if (!string) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> error(aCx);
|
||||
if (!CreateTypeError(aCx, aScript, message, &error)) {
|
||||
if (!JS::CreateError(aCx, JSEXN_TYPEERR, nullptr, filename, aLineNumber,
|
||||
aColumnNumber, nullptr, string, &error)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
@@ -685,28 +678,37 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOu
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JSObject*> moduleRecord(cx, ms->ModuleRecord());
|
||||
JS::Rooted<JSObject*> specifiers(cx, JS::GetRequestedModules(cx, moduleRecord));
|
||||
JS::Rooted<JSObject*> requestedModules(cx);
|
||||
requestedModules = JS::GetRequestedModules(cx, moduleRecord);
|
||||
MOZ_ASSERT(requestedModules);
|
||||
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(cx, specifiers, &length)) {
|
||||
if (!JS_GetArrayLength(cx, requestedModules, &length)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
JS::Rooted<JS::Value> element(cx);
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
if (!JS_GetElement(cx, specifiers, i, &val)) {
|
||||
if (!JS_GetElement(cx, requestedModules, i, &element)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSString*> str(cx, JS::GetRequestedModuleSpecifier(cx, element));
|
||||
MOZ_ASSERT(str);
|
||||
|
||||
nsAutoJSString specifier;
|
||||
if (!specifier.init(cx, val)) {
|
||||
if (!specifier.init(cx, str)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Let url be the result of resolving a module specifier given module script and requested.
|
||||
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(ms, specifier);
|
||||
if (!uri) {
|
||||
nsresult rv = HandleResolveFailure(cx, ms, specifier);
|
||||
uint32_t lineNumber = 0;
|
||||
uint32_t columnNumber = 0;
|
||||
JS::GetRequestedModuleSourcePos(cx, element, &lineNumber, &columnNumber);
|
||||
|
||||
nsresult rv = HandleResolveFailure(cx, ms, specifier, lineNumber, columnNumber);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@@ -798,14 +800,19 @@ ScriptLoader::StartFetchingModuleAndDependencies(ModuleLoadRequest* aParent,
|
||||
|
||||
// 8.1.3.8.1 HostResolveImportedModule(referencingModule, specifier)
|
||||
JSObject*
|
||||
HostResolveImportedModule(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
||||
JS::Handle<JSString*> aSpecifier)
|
||||
{
|
||||
// Let referencing module script be referencingModule.[[HostDefined]].
|
||||
auto script = static_cast<ModuleScript*>(aReferencingPrivate.toPrivate());
|
||||
MOZ_ASSERT(JS::GetModulePrivate(script->ModuleRecord()) == aReferencingPrivate);
|
||||
JS::Value value = JS::GetModuleHostDefinedField(aModule);
|
||||
auto script = static_cast<ModuleScript*>(value.toPrivate());
|
||||
MOZ_ASSERT(script->ModuleRecord() == aModule);
|
||||
|
||||
// FIXME: in-line module scripts apparently pass a null specifier?
|
||||
// At least make sure that doesn't crash the browser.
|
||||
if (!aSpecifier)
|
||||
return nullptr;
|
||||
|
||||
// Let url be the result of resolving a module specifier given referencing
|
||||
// module script and specifier.
|
||||
nsAutoJSString string;
|
||||
|
||||
@@ -630,9 +630,8 @@ private:
|
||||
ModuleScript* GetFetchedModule(nsIURI* aURL) const;
|
||||
|
||||
friend JSObject*
|
||||
HostResolveImportedModule(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReferencingPrivate,
|
||||
JS::Handle<JSString*> aSpecifier);
|
||||
HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
|
||||
JS::Handle<JSString*> aSpecifier);
|
||||
|
||||
nsresult CreateModuleScript(ModuleLoadRequest* aRequest);
|
||||
nsresult ProcessFetchedModuleSource(ModuleLoadRequest* aRequest);
|
||||
|
||||
+1
-1
@@ -778,7 +778,7 @@ struct JSClass {
|
||||
// application.
|
||||
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
|
||||
#define JSCLASS_GLOBAL_SLOT_COUNT \
|
||||
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 45)
|
||||
(JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProto_LIMIT * 2 + 46)
|
||||
#define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
|
||||
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
|
||||
#define JSCLASS_GLOBAL_FLAGS \
|
||||
|
||||
@@ -363,7 +363,7 @@ function InnerModuleInstantiation(module, stack, index)
|
||||
// Step 9
|
||||
let requestedModules = module.requestedModules;
|
||||
for (let i = 0; i < requestedModules.length; i++) {
|
||||
let required = requestedModules[i];
|
||||
let required = requestedModules[i].moduleSpecifier;
|
||||
let requiredModule = CallModuleResolveHook(module, required, MODULE_STATUS_UNINSTANTIATED);
|
||||
|
||||
index = InnerModuleInstantiation(requiredModule, stack, index);
|
||||
@@ -591,7 +591,7 @@ function InnerModuleEvaluation(module, stack, index)
|
||||
// Step 10
|
||||
let requestedModules = module.requestedModules;
|
||||
for (let i = 0; i < requestedModules.length; i++) {
|
||||
let required = requestedModules[i];
|
||||
let required = requestedModules[i].moduleSpecifier;
|
||||
let requiredModule =
|
||||
CallModuleResolveHook(module, required, MODULE_STATUS_INSTANTIATED);
|
||||
|
||||
|
||||
+110
-38
@@ -125,7 +125,7 @@ GlobalObject::initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return false;
|
||||
|
||||
global->setReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
global->initReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ GlobalObject::initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return false;
|
||||
|
||||
global->setReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
global->initReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -240,6 +240,71 @@ ExportEntryObject::create(ExclusiveContext* cx,
|
||||
return self;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// RequestedModuleObject
|
||||
|
||||
/* static */ const Class
|
||||
RequestedModuleObject::class_ = {
|
||||
"RequestedModule",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(RequestedModuleObject::SlotCount) |
|
||||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
DEFINE_GETTER_FUNCTIONS(RequestedModuleObject, moduleSpecifier, ModuleSpecifierSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(RequestedModuleObject, lineNumber, LineNumberSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(RequestedModuleObject, columnNumber, ColumnNumberSlot)
|
||||
|
||||
DEFINE_ATOM_ACCESSOR_METHOD(RequestedModuleObject, moduleSpecifier)
|
||||
DEFINE_UINT32_ACCESSOR_METHOD(RequestedModuleObject, lineNumber)
|
||||
DEFINE_UINT32_ACCESSOR_METHOD(RequestedModuleObject, columnNumber)
|
||||
|
||||
/* static */ bool
|
||||
RequestedModuleObject::isInstance(HandleValue value)
|
||||
{
|
||||
return value.isObject() && value.toObject().is<RequestedModuleObject>();
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
GlobalObject::initRequestedModuleProto(JSContext* cx, Handle<GlobalObject*> global)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("moduleSpecifier", RequestedModuleObject_moduleSpecifierGetter, 0),
|
||||
JS_PSG("lineNumber", RequestedModuleObject_lineNumberGetter, 0),
|
||||
JS_PSG("columnNumber", RequestedModuleObject_columnNumberGetter, 0),
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
RootedObject proto(cx, GlobalObject::createBlankPrototype<PlainObject>(cx, global));
|
||||
if (!proto)
|
||||
return false;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return false;
|
||||
|
||||
global->initReservedSlot(REQUESTED_MODULE_PROTO, ObjectValue(*proto));
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ RequestedModuleObject*
|
||||
RequestedModuleObject::create(JSContext* cx,
|
||||
HandleAtom moduleSpecifier,
|
||||
uint32_t lineNumber,
|
||||
uint32_t columnNumber)
|
||||
{
|
||||
MOZ_ASSERT(lineNumber > 0);
|
||||
|
||||
RootedObject proto(cx, cx->global()->getRequestedModulePrototype());
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
RootedRequestedModuleObject self(cx, &obj->as<RequestedModuleObject>());
|
||||
self->initReservedSlot(ModuleSpecifierSlot, StringValue(moduleSpecifier));
|
||||
self->initReservedSlot(LineNumberSlot, Int32Value(lineNumber));
|
||||
self->initReservedSlot(ColumnNumberSlot, Int32Value(columnNumber));
|
||||
return self;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IndirectBindingMap
|
||||
|
||||
@@ -725,12 +790,6 @@ ModuleObject::namespace_()
|
||||
return &value.toObject().as<ModuleNamespaceObject>();
|
||||
}
|
||||
|
||||
ScriptSourceObject*
|
||||
ModuleObject::scriptSourceObject() const
|
||||
{
|
||||
return &getReservedSlot(ScriptSourceObjectSlot).toObject().as<ScriptSourceObject>();
|
||||
}
|
||||
|
||||
FunctionDeclarationVector*
|
||||
ModuleObject::functionDeclarations()
|
||||
{
|
||||
@@ -744,10 +803,8 @@ ModuleObject::functionDeclarations()
|
||||
void
|
||||
ModuleObject::init(HandleScript script)
|
||||
{
|
||||
MOZ_ASSERT(script);
|
||||
initReservedSlot(ScriptSlot, PrivateValue(script));
|
||||
initReservedSlot(StatusSlot, Int32Value(MODULE_STATUS_UNINSTANTIATED));
|
||||
initReservedSlot(ScriptSourceObjectSlot, ObjectValue(script->scriptSourceUnwrap()));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -876,6 +933,18 @@ ModuleObject::evaluationError() const
|
||||
return getReservedSlot(EvaluationErrorSlot);
|
||||
}
|
||||
|
||||
Value
|
||||
ModuleObject::hostDefinedField() const
|
||||
{
|
||||
return getReservedSlot(HostDefinedSlot);
|
||||
}
|
||||
|
||||
void
|
||||
ModuleObject::setHostDefinedField(const JS::Value& value)
|
||||
{
|
||||
setReservedSlot(HostDefinedSlot, value);
|
||||
}
|
||||
|
||||
Scope*
|
||||
ModuleObject::enclosingScope() const
|
||||
{
|
||||
@@ -1070,7 +1139,8 @@ ModuleBuilder::ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
|
||||
: cx_(cx),
|
||||
module_(cx, module),
|
||||
tokenStream_(tokenStream),
|
||||
requestedModules_(cx, AtomVector(cx)),
|
||||
requestedModuleSpecifiers_(cx, AtomSet(cx)),
|
||||
requestedModules_(cx, RequestedModuleVector(cx)),
|
||||
importedBoundNames_(cx, AtomVector(cx)),
|
||||
importEntries_(cx, ImportEntryVector(cx)),
|
||||
exportEntries_(cx, ExportEntryVector(cx)),
|
||||
@@ -1079,6 +1149,12 @@ ModuleBuilder::ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
|
||||
starExportEntries_(cx, ExportEntryVector(cx))
|
||||
{}
|
||||
|
||||
bool
|
||||
ModuleBuilder::init()
|
||||
{
|
||||
return requestedModuleSpecifiers_.init();
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleBuilder::buildTables()
|
||||
{
|
||||
@@ -1126,24 +1202,23 @@ ModuleBuilder::buildTables()
|
||||
bool
|
||||
ModuleBuilder::initModule()
|
||||
{
|
||||
RootedArrayObject requestedModules(cx_, createArray<JSAtom*>(requestedModules_));
|
||||
RootedArrayObject requestedModules(cx_, createArray(requestedModules_));
|
||||
if (!requestedModules)
|
||||
return false;
|
||||
|
||||
RootedArrayObject importEntries(cx_, createArray<ImportEntryObject*>(importEntries_));
|
||||
RootedArrayObject importEntries(cx_, createArray(importEntries_));
|
||||
if (!importEntries)
|
||||
return false;
|
||||
|
||||
RootedArrayObject localExportEntries(cx_, createArray<ExportEntryObject*>(localExportEntries_));
|
||||
RootedArrayObject localExportEntries(cx_, createArray(localExportEntries_));
|
||||
if (!localExportEntries)
|
||||
return false;
|
||||
|
||||
RootedArrayObject indirectExportEntries(cx_);
|
||||
indirectExportEntries = createArray<ExportEntryObject*>(indirectExportEntries_);
|
||||
RootedArrayObject indirectExportEntries(cx_, createArray(indirectExportEntries_));
|
||||
if (!indirectExportEntries)
|
||||
return false;
|
||||
|
||||
RootedArrayObject starExportEntries(cx_, createArray<ExportEntryObject*>(starExportEntries_));
|
||||
RootedArrayObject starExportEntries(cx_, createArray(starExportEntries_));
|
||||
if (!starExportEntries)
|
||||
return false;
|
||||
|
||||
@@ -1165,7 +1240,7 @@ ModuleBuilder::processImport(frontend::ParseNode* pn)
|
||||
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
|
||||
|
||||
RootedAtom module(cx_, pn->pn_right->pn_atom);
|
||||
if (!maybeAppendRequestedModule(module))
|
||||
if (!maybeAppendRequestedModule(module, pn->pn_right))
|
||||
return false;
|
||||
|
||||
for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) {
|
||||
@@ -1273,7 +1348,7 @@ ModuleBuilder::processExportFrom(frontend::ParseNode* pn)
|
||||
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
|
||||
|
||||
RootedAtom module(cx_, pn->pn_right->pn_atom);
|
||||
if (!maybeAppendRequestedModule(module))
|
||||
if (!maybeAppendRequestedModule(module, pn->pn_right))
|
||||
return false;
|
||||
|
||||
for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) {
|
||||
@@ -1342,29 +1417,26 @@ ModuleBuilder::appendExportFromEntry(HandleAtom exportName, HandleAtom moduleReq
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleBuilder::maybeAppendRequestedModule(HandleAtom module)
|
||||
ModuleBuilder::maybeAppendRequestedModule(HandleAtom specifier, ParseNode* node)
|
||||
{
|
||||
for (auto m : requestedModules_) {
|
||||
if (m == module)
|
||||
return true;
|
||||
if (requestedModuleSpecifiers_.has(specifier)) {
|
||||
return true;
|
||||
}
|
||||
return requestedModules_.append(module);
|
||||
}
|
||||
|
||||
static Value
|
||||
MakeElementValue(JSString *string)
|
||||
{
|
||||
return StringValue(string);
|
||||
}
|
||||
|
||||
static Value
|
||||
MakeElementValue(JSObject *object)
|
||||
{
|
||||
return ObjectValue(*object);
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
tokenStream_.srcCoords.lineNumAndColumnIndex(node->pn_pos.begin, &line, &column);
|
||||
JSContext* cx = reinterpret_cast<JSContext*>(cx_);
|
||||
RootedRequestedModuleObject req(cx, RequestedModuleObject::create(cx, specifier, line, column));
|
||||
if (!req) {
|
||||
return false;
|
||||
}
|
||||
return FreezeObject(cx, req) &&
|
||||
requestedModules_.append(req) &&
|
||||
requestedModuleSpecifiers_.put(specifier);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ArrayObject* ModuleBuilder::createArray(const GCVector<T>& vector)
|
||||
ArrayObject* ModuleBuilder::createArray(const JS::Rooted<GCVector<T>>& vector)
|
||||
{
|
||||
uint32_t length = vector.length();
|
||||
RootedArrayObject array(cx_, NewDenseFullyAllocatedArray(cx_, length));
|
||||
@@ -1373,7 +1445,7 @@ ArrayObject* ModuleBuilder::createArray(const GCVector<T>& vector)
|
||||
|
||||
array->setDenseInitializedLength(length);
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
array->initDenseElement(i, MakeElementValue(vector[i]));
|
||||
array->initDenseElement(i, ObjectValue(*vector[i]));
|
||||
|
||||
return array;
|
||||
}
|
||||
@@ -100,6 +100,32 @@ class ExportEntryObject : public NativeObject
|
||||
typedef Rooted<ExportEntryObject*> RootedExportEntryObject;
|
||||
typedef Handle<ExportEntryObject*> HandleExportEntryObject;
|
||||
|
||||
class RequestedModuleObject : public NativeObject
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ModuleSpecifierSlot = 0,
|
||||
LineNumberSlot,
|
||||
ColumnNumberSlot,
|
||||
SlotCount
|
||||
};
|
||||
|
||||
static const Class class_;
|
||||
static JSObject* initClass(JSContext* cx, HandleObject obj);
|
||||
static bool isInstance(HandleValue value);
|
||||
static RequestedModuleObject* create(JSContext* cx,
|
||||
HandleAtom moduleSpecifier,
|
||||
uint32_t lineNumber,
|
||||
uint32_t columnNumber);
|
||||
JSAtom* moduleSpecifier() const;
|
||||
uint32_t lineNumber() const;
|
||||
uint32_t columnNumber() const;
|
||||
};
|
||||
|
||||
typedef Rooted<RequestedModuleObject*> RootedRequestedModuleObject;
|
||||
typedef Handle<RequestedModuleObject*> HandleRequestedModuleObject;
|
||||
|
||||
class IndirectBindingMap
|
||||
{
|
||||
public:
|
||||
@@ -219,7 +245,7 @@ class ModuleObject : public NativeObject
|
||||
NamespaceSlot,
|
||||
StatusSlot,
|
||||
EvaluationErrorSlot,
|
||||
ScriptSourceObjectSlot,
|
||||
HostDefinedSlot,
|
||||
RequestedModulesSlot,
|
||||
ImportEntriesSlot,
|
||||
LocalExportEntriesSlot,
|
||||
@@ -271,7 +297,7 @@ class ModuleObject : public NativeObject
|
||||
ModuleStatus status() const;
|
||||
bool hadEvaluationError() const;
|
||||
Value evaluationError() const;
|
||||
ScriptSourceObject* scriptSourceObject() const;
|
||||
Value hostDefinedField() const;
|
||||
ArrayObject& requestedModules() const;
|
||||
ArrayObject& importEntries() const;
|
||||
ArrayObject& localExportEntries() const;
|
||||
@@ -284,6 +310,8 @@ class ModuleObject : public NativeObject
|
||||
static bool Instantiate(JSContext* cx, HandleModuleObject self);
|
||||
static bool Evaluate(JSContext* cx, HandleModuleObject self);
|
||||
|
||||
void setHostDefinedField(const JS::Value& value);
|
||||
|
||||
// For BytecodeEmitter.
|
||||
bool noteFunctionDeclaration(ExclusiveContext* cx, HandleAtom name, HandleFunction fun);
|
||||
|
||||
@@ -316,6 +344,8 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
explicit ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
|
||||
const frontend::TokenStream& tokenStream);
|
||||
|
||||
bool init();
|
||||
|
||||
bool processImport(frontend::ParseNode* pn);
|
||||
bool processExport(frontend::ParseNode* pn);
|
||||
bool processExportFrom(frontend::ParseNode* pn);
|
||||
@@ -332,15 +362,20 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
|
||||
private:
|
||||
using AtomVector = GCVector<JSAtom*>;
|
||||
using RootedAtomVector = JS::Rooted<AtomVector>;
|
||||
using ImportEntryVector = GCVector<ImportEntryObject*>;
|
||||
using RequestedModuleVector = GCVector<RequestedModuleObject*>;
|
||||
using AtomSet = JS::GCHashSet<JSAtom*>;
|
||||
using RootedAtomVector = JS::Rooted<AtomVector>;
|
||||
using RootedImportEntryVector = JS::Rooted<ImportEntryVector>;
|
||||
using RootedExportEntryVector = JS::Rooted<ExportEntryVector>;
|
||||
using RootedRequestedModuleVector = JS::Rooted<RequestedModuleVector>;
|
||||
using RootedAtomSet = JS::Rooted<AtomSet>;
|
||||
|
||||
ExclusiveContext* cx_;
|
||||
RootedModuleObject module_;
|
||||
const frontend::TokenStream& tokenStream_;
|
||||
RootedAtomVector requestedModules_;
|
||||
RootedAtomSet requestedModuleSpecifiers_;
|
||||
RootedRequestedModuleVector requestedModules_;
|
||||
RootedAtomVector importedBoundNames_;
|
||||
RootedImportEntryVector importEntries_;
|
||||
RootedExportEntryVector exportEntries_;
|
||||
@@ -355,10 +390,10 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
bool appendExportFromEntry(HandleAtom exportName, HandleAtom moduleRequest,
|
||||
HandleAtom importName, frontend::ParseNode* node);
|
||||
|
||||
bool maybeAppendRequestedModule(HandleAtom module);
|
||||
bool maybeAppendRequestedModule(HandleAtom specifier, frontend::ParseNode* node);
|
||||
|
||||
template <typename T>
|
||||
ArrayObject* createArray(const GCVector<T>& vector);
|
||||
ArrayObject* createArray(const JS::Rooted<GCVector<T>>& vector);
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
@@ -3741,6 +3741,9 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
|
||||
return false;
|
||||
|
||||
ModuleBuilder builder(cx, module, parser.tokenStream);
|
||||
if (!builder.init())
|
||||
return false;
|
||||
|
||||
ModuleSharedContext modulesc(cx, module, &cx->global()->emptyGlobalScope(), builder);
|
||||
pn = parser.moduleBody(&modulesc);
|
||||
if (!pn)
|
||||
|
||||
@@ -405,6 +405,9 @@ BytecodeCompiler::compileModule()
|
||||
module->init(script);
|
||||
|
||||
ModuleBuilder builder(cx, module, parser->tokenStream);
|
||||
if (!builder.init())
|
||||
return nullptr;
|
||||
|
||||
ModuleSharedContext modulesc(cx, module, enclosingScope, builder);
|
||||
ParseNode* pn = parser->moduleBody(&modulesc);
|
||||
if (!pn)
|
||||
|
||||
@@ -46,6 +46,7 @@ class RegExpObject;
|
||||
class SavedFrame;
|
||||
class Scope;
|
||||
class EnvironmentObject;
|
||||
class RequestedModuleObject;
|
||||
class ScriptSourceObject;
|
||||
class Shape;
|
||||
class SharedArrayBufferObject;
|
||||
@@ -84,6 +85,7 @@ class JitCode;
|
||||
D(js::PlainObject*) \
|
||||
D(js::PropertyName*) \
|
||||
D(js::RegExpObject*) \
|
||||
D(js::RequestedModuleObject*) \
|
||||
D(js::SavedFrame*) \
|
||||
D(js::Scope*) \
|
||||
D(js::ScriptSourceObject*) \
|
||||
|
||||
@@ -5,7 +5,7 @@ function testRequestedModules(source, expected) {
|
||||
var actual = module.requestedModules;
|
||||
assertEq(actual.length, expected.length);
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
assertEq(actual[i], expected[i]);
|
||||
assertEq(actual[i].moduleSpecifier, expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-20
@@ -4691,27 +4691,15 @@ JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::SetModulePrivate(JSObject* module, const JS::Value& value)
|
||||
JS::SetModuleHostDefinedField(JSObject* module, const JS::Value& value)
|
||||
{
|
||||
module->as<ModuleObject>().scriptSourceObject()->setPrivate(value);
|
||||
module->as<ModuleObject>().setHostDefinedField(value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JS::Value)
|
||||
JS::GetModulePrivate(JSObject* module)
|
||||
JS::GetModuleHostDefinedField(JSObject* module)
|
||||
{
|
||||
return module->as<ModuleObject>().scriptSourceObject()->getPrivate();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::SetScriptPrivate(JSScript* script, const JS::Value& value)
|
||||
{
|
||||
script->scriptSourceUnwrap().setPrivate(value);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JS::Value)
|
||||
JS::GetScriptPrivate(JSScript* script)
|
||||
{
|
||||
return script->scriptSourceUnwrap().getPrivate();
|
||||
return module->as<ModuleObject>().hostDefinedField();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
@@ -4741,13 +4729,28 @@ JS::GetRequestedModules(JSContext* cx, JS::HandleObject moduleArg)
|
||||
return &moduleArg->as<ModuleObject>().requestedModules();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSScript*)
|
||||
JS::GetModuleScript(JSContext* cx, JS::HandleObject moduleArg)
|
||||
JS_PUBLIC_API(JSString*)
|
||||
JS::GetRequestedModuleSpecifier(JSContext* cx, JS::HandleValue value)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, moduleArg);
|
||||
return moduleArg->as<ModuleObject>().script();
|
||||
assertSameCompartment(cx, value);
|
||||
JSObject* obj = &value.toObject();
|
||||
return obj->as<RequestedModuleObject>().moduleSpecifier();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS::GetRequestedModuleSourcePos(JSContext* cx, JS::HandleValue value,
|
||||
uint32_t* lineNumber, uint32_t* columnNumber)
|
||||
{
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, value);
|
||||
MOZ_ASSERT(lineNumber);
|
||||
MOZ_ASSERT(columnNumber);
|
||||
auto& requested = value.toObject().as<RequestedModuleObject>();
|
||||
*lineNumber = requested.lineNumber();
|
||||
*columnNumber = requested.columnNumber();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObject*)
|
||||
|
||||
+23
-27
@@ -4324,7 +4324,7 @@ extern JS_PUBLIC_API(bool)
|
||||
Evaluate(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
const char* filename, JS::MutableHandleValue rval);
|
||||
|
||||
using ModuleResolveHook = JSObject* (*)(JSContext*, HandleValue, HandleString);
|
||||
using ModuleResolveHook = JSObject* (*)(JSContext*, HandleObject, HandleString);
|
||||
|
||||
/**
|
||||
* Get the HostResolveImportedModule hook for the runtime.
|
||||
@@ -4347,30 +4347,17 @@ CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
SourceBufferHolder& srcBuf, JS::MutableHandleObject moduleRecord);
|
||||
|
||||
/**
|
||||
* Set a private value associated with a source text module record.
|
||||
* Set the [[HostDefined]] field of a source text module record to the given
|
||||
* value.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
SetModulePrivate(JSObject* module, const JS::Value& value);
|
||||
SetModuleHostDefinedField(JSObject* module, const JS::Value& value);
|
||||
|
||||
/**
|
||||
* Get the private value associated with a source text module record.
|
||||
* Get the [[HostDefined]] field of a source text module record.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JS::Value)
|
||||
GetModulePrivate(JSObject* module);
|
||||
|
||||
/**
|
||||
* Set a private value associated with a script. Note that this value is shared
|
||||
* by all nested scripts compiled from a single source file.
|
||||
*/
|
||||
extern JS_PUBLIC_API(void)
|
||||
SetScriptPrivate(JSScript* script, const JS::Value& value);
|
||||
|
||||
/**
|
||||
* Get the private value associated with a script. Note that this value is
|
||||
* shared by all nested scripts compiled from a single source file.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JS::Value)
|
||||
GetScriptPrivate(JSScript* script);
|
||||
GetModuleHostDefinedField(JSObject* module);
|
||||
|
||||
/*
|
||||
* Perform the ModuleInstantiate operation on the given source text module
|
||||
@@ -4399,18 +4386,27 @@ ModuleEvaluate(JSContext* cx, JS::HandleObject moduleRecord);
|
||||
* Get a list of the module specifiers used by a source text module
|
||||
* record to request importation of modules.
|
||||
*
|
||||
* The result is a JavaScript array of string values. To extract the individual
|
||||
* values use only JS_GetArrayLength and JS_GetElement with indices 0 to
|
||||
* length - 1.
|
||||
* The result is a JavaScript array of object values. To extract the individual
|
||||
* values use only JS_GetArrayLength and JS_GetElement with indices 0 to length
|
||||
* - 1.
|
||||
*
|
||||
* The element values are objects with the following properties:
|
||||
* - moduleSpecifier: the module specifier string
|
||||
* - lineNumber: the line number of the import in the source text
|
||||
* - columnNumber: the column number of the import in the source text
|
||||
*
|
||||
* These property values can be extracted with GetRequestedModuleSpecifier() and
|
||||
* GetRequestedModuleSourcePos()
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject*)
|
||||
GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
|
||||
|
||||
/*
|
||||
* Get the script associated with a module.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSScript*)
|
||||
GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord);
|
||||
extern JS_PUBLIC_API(JSString*)
|
||||
GetRequestedModuleSpecifier(JSContext* cx, JS::HandleValue requestedModuleObject);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
GetRequestedModuleSourcePos(JSContext* cx, JS::HandleValue requestedModuleObject,
|
||||
uint32_t* lineNumber, uint32_t* columnNumber);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
|
||||
+5
-15
@@ -638,22 +638,12 @@ class ScriptSourceObject : public NativeObject
|
||||
return static_cast<JSScript*>(untyped);
|
||||
}
|
||||
|
||||
void setPrivate(const Value& value) {
|
||||
setReservedSlot(PRIVATE_SLOT, value);
|
||||
}
|
||||
Value getPrivate() const {
|
||||
return getReservedSlot(PRIVATE_SLOT);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
SOURCE_SLOT = 0,
|
||||
ELEMENT_SLOT,
|
||||
ELEMENT_PROPERTY_SLOT,
|
||||
INTRODUCTION_SCRIPT_SLOT,
|
||||
PRIVATE_SLOT,
|
||||
RESERVED_SLOTS
|
||||
};
|
||||
static const uint32_t SOURCE_SLOT = 0;
|
||||
static const uint32_t ELEMENT_SLOT = 1;
|
||||
static const uint32_t ELEMENT_PROPERTY_SLOT = 2;
|
||||
static const uint32_t INTRODUCTION_SCRIPT_SLOT = 3;
|
||||
static const uint32_t RESERVED_SLOTS = 4;
|
||||
};
|
||||
|
||||
enum GeneratorKind { NotGenerator, LegacyGenerator, StarGenerator };
|
||||
|
||||
+2
-57
@@ -4039,12 +4039,12 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
static JSObject*
|
||||
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
|
||||
CallModuleResolveHook(JSContext* cx, HandleObject module, HandleString specifier)
|
||||
{
|
||||
ShellContext* sc = GetShellContext(cx);
|
||||
|
||||
JS::AutoValueArray<2> args(cx);
|
||||
args[0].set(referencingPrivate);
|
||||
args[0].setObject(*module);
|
||||
args[1].setString(specifier);
|
||||
|
||||
RootedValue result(cx);
|
||||
@@ -4059,53 +4059,6 @@ CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleStrin
|
||||
return &result.toObject();
|
||||
}
|
||||
|
||||
static bool
|
||||
ReportArgumentTypeError(JSContext* cx, HandleValue value, const char* expected)
|
||||
{
|
||||
const char* typeName = InformalValueTypeName(value);
|
||||
JS_ReportErrorASCII(cx, "Expected %s, got %s", expected, typeName);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
ShellSetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() != 2) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||
"setModulePrivate", "0", "s");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
|
||||
return ReportArgumentTypeError(cx, args[0], "module object");
|
||||
}
|
||||
|
||||
JS::SetModulePrivate(&args[0].toObject(), args[1]);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
ShellGetModulePrivate(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (args.length() != 1) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||
"getModulePrivate", "0", "s");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!args[0].isObject() || !args[0].toObject().is<ModuleObject>()) {
|
||||
return ReportArgumentTypeError(cx, args[0], "module object");
|
||||
}
|
||||
|
||||
args.rval().set(JS::GetModulePrivate(&args[0].toObject()));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
@@ -5974,14 +5927,6 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||
" This hook is used to look up a previously loaded module object. It should\n"
|
||||
" be implemented by the module loader."),
|
||||
|
||||
JS_FN_HELP("setModulePrivate", ShellSetModulePrivate, 2, 0,
|
||||
"setModulePrivate(scriptObject, privateValue)",
|
||||
" Associate a private value with a module object.\n"),
|
||||
|
||||
JS_FN_HELP("getModulePrivate", ShellGetModulePrivate, 2, 0,
|
||||
"getModulePrivate(scriptObject)",
|
||||
" Get the private value associated with a module object.\n"),
|
||||
|
||||
JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
|
||||
"getModuleLoadPath()",
|
||||
" Return any --module-load-path argument passed to the shell. Used by the\n"
|
||||
|
||||
@@ -112,6 +112,7 @@ class GlobalObject : public NativeObject
|
||||
MODULE_PROTO,
|
||||
IMPORT_ENTRY_PROTO,
|
||||
EXPORT_ENTRY_PROTO,
|
||||
REQUESTED_MODULE_PROTO,
|
||||
REGEXP_STATICS,
|
||||
WARNED_ONCE_FLAGS,
|
||||
RUNTIME_CODEGEN_ENABLED,
|
||||
@@ -524,6 +525,11 @@ class GlobalObject : public NativeObject
|
||||
return value.isUndefined() ? nullptr : &value.toObject();
|
||||
}
|
||||
|
||||
JSObject* maybeGetRequestedModulePrototype() {
|
||||
Value value = getSlot(REQUESTED_MODULE_PROTO);
|
||||
return value.isUndefined() ? nullptr : &value.toObject();
|
||||
}
|
||||
|
||||
JSObject* getModulePrototype() {
|
||||
JSObject* proto = maybeGetModulePrototype();
|
||||
MOZ_ASSERT(proto);
|
||||
@@ -542,6 +548,12 @@ class GlobalObject : public NativeObject
|
||||
return proto;
|
||||
}
|
||||
|
||||
JSObject* getRequestedModulePrototype() {
|
||||
JSObject* proto = maybeGetRequestedModulePrototype();
|
||||
MOZ_ASSERT(proto);
|
||||
return proto;
|
||||
}
|
||||
|
||||
static JSFunction*
|
||||
getOrCreateTypedArrayConstructor(JSContext* cx, Handle<GlobalObject*> global) {
|
||||
if (!ensureConstructor(cx, global, JSProto_TypedArray))
|
||||
@@ -831,6 +843,7 @@ class GlobalObject : public NativeObject
|
||||
static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
static bool initRequestedModuleProto(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
// Implemented in builtin/TypedObject.cpp
|
||||
static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
@@ -2035,8 +2035,7 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
||||
}
|
||||
|
||||
RootedObject result(cx);
|
||||
RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
|
||||
result = moduleResolveHook(cx, referencingPrivate, specifier);
|
||||
result = moduleResolveHook(cx, module, specifier);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
|
||||
Reference in new issue
Block a user