Compare commits

...
12 changed files with 233 additions and 80 deletions

No files matched your search

+37 -30
View File
@@ -599,38 +599,31 @@ ScriptLoader::CreateModuleScript(ModuleLoadRequest* aRequest)
return rv; 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 static nsresult
HandleResolveFailure(JSContext* aCx, ModuleScript* aScript, 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: ")); nsAutoString message(NS_LITERAL_STRING("Error resolving module specifier: "));
message.Append(aSpecifier); 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); 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; return NS_ERROR_OUT_OF_MEMORY;
} }
@@ -685,28 +678,37 @@ ResolveRequestedModules(ModuleLoadRequest* aRequest, nsCOMArray<nsIURI>* aUrlsOu
JSContext* cx = jsapi.cx(); JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> moduleRecord(cx, ms->ModuleRecord()); 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; uint32_t length;
if (!JS_GetArrayLength(cx, specifiers, &length)) { if (!JS_GetArrayLength(cx, requestedModules, &length)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
JS::Rooted<JS::Value> val(cx); JS::Rooted<JS::Value> element(cx);
for (uint32_t i = 0; i < length; i++) { 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; return NS_ERROR_FAILURE;
} }
JS::Rooted<JSString*> str(cx, JS::GetRequestedModuleSpecifier(cx, element));
MOZ_ASSERT(str);
nsAutoJSString specifier; nsAutoJSString specifier;
if (!specifier.init(cx, val)) { if (!specifier.init(cx, str)) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
// Let url be the result of resolving a module specifier given module script and requested. // Let url be the result of resolving a module specifier given module script and requested.
nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(ms, specifier); nsCOMPtr<nsIURI> uri = ResolveModuleSpecifier(ms, specifier);
if (!uri) { 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); NS_ENSURE_SUCCESS(rv, rv);
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@@ -806,6 +808,11 @@ HostResolveImportedModule(JSContext* aCx, JS::Handle<JSObject*> aModule,
auto script = static_cast<ModuleScript*>(value.toPrivate()); auto script = static_cast<ModuleScript*>(value.toPrivate());
MOZ_ASSERT(script->ModuleRecord() == aModule); 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 // Let url be the result of resolving a module specifier given referencing
// module script and specifier. // module script and specifier.
nsAutoJSString string; nsAutoJSString string;
+1 -1
View File
@@ -778,7 +778,7 @@ struct JSClass {
// application. // application.
#define JSCLASS_GLOBAL_APPLICATION_SLOTS 5 #define JSCLASS_GLOBAL_APPLICATION_SLOTS 5
#define JSCLASS_GLOBAL_SLOT_COUNT \ #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) \ #define JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(n) \
(JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n))) (JSCLASS_IS_GLOBAL | JSCLASS_HAS_RESERVED_SLOTS(JSCLASS_GLOBAL_SLOT_COUNT + (n)))
#define JSCLASS_GLOBAL_FLAGS \ #define JSCLASS_GLOBAL_FLAGS \
+2 -2
View File
@@ -363,7 +363,7 @@ function InnerModuleInstantiation(module, stack, index)
// Step 9 // Step 9
let requestedModules = module.requestedModules; let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) { 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); let requiredModule = CallModuleResolveHook(module, required, MODULE_STATUS_UNINSTANTIATED);
index = InnerModuleInstantiation(requiredModule, stack, index); index = InnerModuleInstantiation(requiredModule, stack, index);
@@ -591,7 +591,7 @@ function InnerModuleEvaluation(module, stack, index)
// Step 10 // Step 10
let requestedModules = module.requestedModules; let requestedModules = module.requestedModules;
for (let i = 0; i < requestedModules.length; i++) { for (let i = 0; i < requestedModules.length; i++) {
let required = requestedModules[i]; let required = requestedModules[i].moduleSpecifier;
let requiredModule = let requiredModule =
CallModuleResolveHook(module, required, MODULE_STATUS_INSTANTIATED); CallModuleResolveHook(module, required, MODULE_STATUS_INSTANTIATED);
+98 -30
View File
@@ -125,7 +125,7 @@ GlobalObject::initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr)) if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
return false; return false;
global->setReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto)); global->initReservedSlot(IMPORT_ENTRY_PROTO, ObjectValue(*proto));
return true; return true;
} }
@@ -203,7 +203,7 @@ GlobalObject::initExportEntryProto(JSContext* cx, Handle<GlobalObject*> global)
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr)) if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
return false; return false;
global->setReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto)); global->initReservedSlot(EXPORT_ENTRY_PROTO, ObjectValue(*proto));
return true; return true;
} }
@@ -240,6 +240,71 @@ ExportEntryObject::create(ExclusiveContext* cx,
return self; 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 // IndirectBindingMap
@@ -1074,7 +1139,8 @@ ModuleBuilder::ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
: cx_(cx), : cx_(cx),
module_(cx, module), module_(cx, module),
tokenStream_(tokenStream), tokenStream_(tokenStream),
requestedModules_(cx, AtomVector(cx)), requestedModuleSpecifiers_(cx, AtomSet(cx)),
requestedModules_(cx, RequestedModuleVector(cx)),
importedBoundNames_(cx, AtomVector(cx)), importedBoundNames_(cx, AtomVector(cx)),
importEntries_(cx, ImportEntryVector(cx)), importEntries_(cx, ImportEntryVector(cx)),
exportEntries_(cx, ExportEntryVector(cx)), exportEntries_(cx, ExportEntryVector(cx)),
@@ -1083,6 +1149,12 @@ ModuleBuilder::ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
starExportEntries_(cx, ExportEntryVector(cx)) starExportEntries_(cx, ExportEntryVector(cx))
{} {}
bool
ModuleBuilder::init()
{
return requestedModuleSpecifiers_.init();
}
bool bool
ModuleBuilder::buildTables() ModuleBuilder::buildTables()
{ {
@@ -1130,24 +1202,23 @@ ModuleBuilder::buildTables()
bool bool
ModuleBuilder::initModule() ModuleBuilder::initModule()
{ {
RootedArrayObject requestedModules(cx_, createArray<JSAtom*>(requestedModules_)); RootedArrayObject requestedModules(cx_, createArray(requestedModules_));
if (!requestedModules) if (!requestedModules)
return false; return false;
RootedArrayObject importEntries(cx_, createArray<ImportEntryObject*>(importEntries_)); RootedArrayObject importEntries(cx_, createArray(importEntries_));
if (!importEntries) if (!importEntries)
return false; return false;
RootedArrayObject localExportEntries(cx_, createArray<ExportEntryObject*>(localExportEntries_)); RootedArrayObject localExportEntries(cx_, createArray(localExportEntries_));
if (!localExportEntries) if (!localExportEntries)
return false; return false;
RootedArrayObject indirectExportEntries(cx_); RootedArrayObject indirectExportEntries(cx_, createArray(indirectExportEntries_));
indirectExportEntries = createArray<ExportEntryObject*>(indirectExportEntries_);
if (!indirectExportEntries) if (!indirectExportEntries)
return false; return false;
RootedArrayObject starExportEntries(cx_, createArray<ExportEntryObject*>(starExportEntries_)); RootedArrayObject starExportEntries(cx_, createArray(starExportEntries_));
if (!starExportEntries) if (!starExportEntries)
return false; return false;
@@ -1169,7 +1240,7 @@ ModuleBuilder::processImport(frontend::ParseNode* pn)
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING)); MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
RootedAtom module(cx_, pn->pn_right->pn_atom); RootedAtom module(cx_, pn->pn_right->pn_atom);
if (!maybeAppendRequestedModule(module)) if (!maybeAppendRequestedModule(module, pn->pn_right))
return false; return false;
for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) { for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) {
@@ -1277,7 +1348,7 @@ ModuleBuilder::processExportFrom(frontend::ParseNode* pn)
MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING)); MOZ_ASSERT(pn->pn_right->isKind(PNK_STRING));
RootedAtom module(cx_, pn->pn_right->pn_atom); RootedAtom module(cx_, pn->pn_right->pn_atom);
if (!maybeAppendRequestedModule(module)) if (!maybeAppendRequestedModule(module, pn->pn_right))
return false; return false;
for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) { for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) {
@@ -1346,29 +1417,26 @@ ModuleBuilder::appendExportFromEntry(HandleAtom exportName, HandleAtom moduleReq
} }
bool bool
ModuleBuilder::maybeAppendRequestedModule(HandleAtom module) ModuleBuilder::maybeAppendRequestedModule(HandleAtom specifier, ParseNode* node)
{ {
for (auto m : requestedModules_) { if (requestedModuleSpecifiers_.has(specifier)) {
if (m == module) return true;
return true;
} }
return requestedModules_.append(module); uint32_t line;
} uint32_t column;
tokenStream_.srcCoords.lineNumAndColumnIndex(node->pn_pos.begin, &line, &column);
static Value JSContext* cx = reinterpret_cast<JSContext*>(cx_);
MakeElementValue(JSString *string) RootedRequestedModuleObject req(cx, RequestedModuleObject::create(cx, specifier, line, column));
{ if (!req) {
return StringValue(string); return false;
} }
return FreezeObject(cx, req) &&
static Value requestedModules_.append(req) &&
MakeElementValue(JSObject *object) requestedModuleSpecifiers_.put(specifier);
{
return ObjectValue(*object);
} }
template <typename T> template <typename T>
ArrayObject* ModuleBuilder::createArray(const GCVector<T>& vector) ArrayObject* ModuleBuilder::createArray(const JS::Rooted<GCVector<T>>& vector)
{ {
uint32_t length = vector.length(); uint32_t length = vector.length();
RootedArrayObject array(cx_, NewDenseFullyAllocatedArray(cx_, length)); RootedArrayObject array(cx_, NewDenseFullyAllocatedArray(cx_, length));
@@ -1377,7 +1445,7 @@ ArrayObject* ModuleBuilder::createArray(const GCVector<T>& vector)
array->setDenseInitializedLength(length); array->setDenseInitializedLength(length);
for (uint32_t i = 0; i < length; i++) for (uint32_t i = 0; i < length; i++)
array->initDenseElement(i, MakeElementValue(vector[i])); array->initDenseElement(i, ObjectValue(*vector[i]));
return array; return array;
} }
+37 -4
View File
@@ -100,6 +100,32 @@ class ExportEntryObject : public NativeObject
typedef Rooted<ExportEntryObject*> RootedExportEntryObject; typedef Rooted<ExportEntryObject*> RootedExportEntryObject;
typedef Handle<ExportEntryObject*> HandleExportEntryObject; 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 class IndirectBindingMap
{ {
public: public:
@@ -318,6 +344,8 @@ class MOZ_STACK_CLASS ModuleBuilder
explicit ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module, explicit ModuleBuilder(ExclusiveContext* cx, HandleModuleObject module,
const frontend::TokenStream& tokenStream); const frontend::TokenStream& tokenStream);
bool init();
bool processImport(frontend::ParseNode* pn); bool processImport(frontend::ParseNode* pn);
bool processExport(frontend::ParseNode* pn); bool processExport(frontend::ParseNode* pn);
bool processExportFrom(frontend::ParseNode* pn); bool processExportFrom(frontend::ParseNode* pn);
@@ -334,15 +362,20 @@ class MOZ_STACK_CLASS ModuleBuilder
private: private:
using AtomVector = GCVector<JSAtom*>; using AtomVector = GCVector<JSAtom*>;
using RootedAtomVector = JS::Rooted<AtomVector>;
using ImportEntryVector = GCVector<ImportEntryObject*>; using ImportEntryVector = GCVector<ImportEntryObject*>;
using RequestedModuleVector = GCVector<RequestedModuleObject*>;
using AtomSet = JS::GCHashSet<JSAtom*>;
using RootedAtomVector = JS::Rooted<AtomVector>;
using RootedImportEntryVector = JS::Rooted<ImportEntryVector>; using RootedImportEntryVector = JS::Rooted<ImportEntryVector>;
using RootedExportEntryVector = JS::Rooted<ExportEntryVector>; using RootedExportEntryVector = JS::Rooted<ExportEntryVector>;
using RootedRequestedModuleVector = JS::Rooted<RequestedModuleVector>;
using RootedAtomSet = JS::Rooted<AtomSet>;
ExclusiveContext* cx_; ExclusiveContext* cx_;
RootedModuleObject module_; RootedModuleObject module_;
const frontend::TokenStream& tokenStream_; const frontend::TokenStream& tokenStream_;
RootedAtomVector requestedModules_; RootedAtomSet requestedModuleSpecifiers_;
RootedRequestedModuleVector requestedModules_;
RootedAtomVector importedBoundNames_; RootedAtomVector importedBoundNames_;
RootedImportEntryVector importEntries_; RootedImportEntryVector importEntries_;
RootedExportEntryVector exportEntries_; RootedExportEntryVector exportEntries_;
@@ -357,10 +390,10 @@ class MOZ_STACK_CLASS ModuleBuilder
bool appendExportFromEntry(HandleAtom exportName, HandleAtom moduleRequest, bool appendExportFromEntry(HandleAtom exportName, HandleAtom moduleRequest,
HandleAtom importName, frontend::ParseNode* node); HandleAtom importName, frontend::ParseNode* node);
bool maybeAppendRequestedModule(HandleAtom module); bool maybeAppendRequestedModule(HandleAtom specifier, frontend::ParseNode* node);
template <typename T> template <typename T>
ArrayObject* createArray(const GCVector<T>& vector); ArrayObject* createArray(const JS::Rooted<GCVector<T>>& vector);
}; };
} // namespace js } // namespace js
+3
View File
@@ -3741,6 +3741,9 @@ reflect_parse(JSContext* cx, uint32_t argc, Value* vp)
return false; return false;
ModuleBuilder builder(cx, module, parser.tokenStream); ModuleBuilder builder(cx, module, parser.tokenStream);
if (!builder.init())
return false;
ModuleSharedContext modulesc(cx, module, &cx->global()->emptyGlobalScope(), builder); ModuleSharedContext modulesc(cx, module, &cx->global()->emptyGlobalScope(), builder);
pn = parser.moduleBody(&modulesc); pn = parser.moduleBody(&modulesc);
if (!pn) if (!pn)
+3
View File
@@ -405,6 +405,9 @@ BytecodeCompiler::compileModule()
module->init(script); module->init(script);
ModuleBuilder builder(cx, module, parser->tokenStream); ModuleBuilder builder(cx, module, parser->tokenStream);
if (!builder.init())
return nullptr;
ModuleSharedContext modulesc(cx, module, enclosingScope, builder); ModuleSharedContext modulesc(cx, module, enclosingScope, builder);
ParseNode* pn = parser->moduleBody(&modulesc); ParseNode* pn = parser->moduleBody(&modulesc);
if (!pn) if (!pn)
+2
View File
@@ -46,6 +46,7 @@ class RegExpObject;
class SavedFrame; class SavedFrame;
class Scope; class Scope;
class EnvironmentObject; class EnvironmentObject;
class RequestedModuleObject;
class ScriptSourceObject; class ScriptSourceObject;
class Shape; class Shape;
class SharedArrayBufferObject; class SharedArrayBufferObject;
@@ -84,6 +85,7 @@ class JitCode;
D(js::PlainObject*) \ D(js::PlainObject*) \
D(js::PropertyName*) \ D(js::PropertyName*) \
D(js::RegExpObject*) \ D(js::RegExpObject*) \
D(js::RequestedModuleObject*) \
D(js::SavedFrame*) \ D(js::SavedFrame*) \
D(js::Scope*) \ D(js::Scope*) \
D(js::ScriptSourceObject*) \ D(js::ScriptSourceObject*) \
@@ -5,7 +5,7 @@ function testRequestedModules(source, expected) {
var actual = module.requestedModules; var actual = module.requestedModules;
assertEq(actual.length, expected.length); assertEq(actual.length, expected.length);
for (var i = 0; i < actual.length; i++) { for (var i = 0; i < actual.length; i++) {
assertEq(actual[i], expected[i]); assertEq(actual[i].moduleSpecifier, expected[i]);
} }
} }
+19 -4
View File
@@ -4729,13 +4729,28 @@ JS::GetRequestedModules(JSContext* cx, JS::HandleObject moduleArg)
return &moduleArg->as<ModuleObject>().requestedModules(); return &moduleArg->as<ModuleObject>().requestedModules();
} }
JS_PUBLIC_API(JSScript*) JS_PUBLIC_API(JSString*)
JS::GetModuleScript(JSContext* cx, JS::HandleObject moduleArg) JS::GetRequestedModuleSpecifier(JSContext* cx, JS::HandleValue value)
{ {
AssertHeapIsIdle(cx); AssertHeapIsIdle(cx);
CHECK_REQUEST(cx); CHECK_REQUEST(cx);
assertSameCompartment(cx, moduleArg); assertSameCompartment(cx, value);
return moduleArg->as<ModuleObject>().script(); 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*) JS_PUBLIC_API(JSObject*)
+17 -8
View File
@@ -4386,18 +4386,27 @@ ModuleEvaluate(JSContext* cx, JS::HandleObject moduleRecord);
* Get a list of the module specifiers used by a source text module * Get a list of the module specifiers used by a source text module
* record to request importation of modules. * record to request importation of modules.
* *
* The result is a JavaScript array of string values. To extract the individual * 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 * values use only JS_GetArrayLength and JS_GetElement with indices 0 to length
* length - 1. * - 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*) extern JS_PUBLIC_API(JSObject*)
GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord); GetRequestedModules(JSContext* cx, JS::HandleObject moduleRecord);
/* extern JS_PUBLIC_API(JSString*)
* Get the script associated with a module. GetRequestedModuleSpecifier(JSContext* cx, JS::HandleValue requestedModuleObject);
*/
extern JS_PUBLIC_API(JSScript*) extern JS_PUBLIC_API(void)
GetModuleScript(JSContext* cx, JS::HandleObject moduleRecord); GetRequestedModuleSourcePos(JSContext* cx, JS::HandleValue requestedModuleObject,
uint32_t* lineNumber, uint32_t* columnNumber);
} /* namespace JS */ } /* namespace JS */
+13
View File
@@ -112,6 +112,7 @@ class GlobalObject : public NativeObject
MODULE_PROTO, MODULE_PROTO,
IMPORT_ENTRY_PROTO, IMPORT_ENTRY_PROTO,
EXPORT_ENTRY_PROTO, EXPORT_ENTRY_PROTO,
REQUESTED_MODULE_PROTO,
REGEXP_STATICS, REGEXP_STATICS,
WARNED_ONCE_FLAGS, WARNED_ONCE_FLAGS,
RUNTIME_CODEGEN_ENABLED, RUNTIME_CODEGEN_ENABLED,
@@ -524,6 +525,11 @@ class GlobalObject : public NativeObject
return value.isUndefined() ? nullptr : &value.toObject(); return value.isUndefined() ? nullptr : &value.toObject();
} }
JSObject* maybeGetRequestedModulePrototype() {
Value value = getSlot(REQUESTED_MODULE_PROTO);
return value.isUndefined() ? nullptr : &value.toObject();
}
JSObject* getModulePrototype() { JSObject* getModulePrototype() {
JSObject* proto = maybeGetModulePrototype(); JSObject* proto = maybeGetModulePrototype();
MOZ_ASSERT(proto); MOZ_ASSERT(proto);
@@ -542,6 +548,12 @@ class GlobalObject : public NativeObject
return proto; return proto;
} }
JSObject* getRequestedModulePrototype() {
JSObject* proto = maybeGetRequestedModulePrototype();
MOZ_ASSERT(proto);
return proto;
}
static JSFunction* static JSFunction*
getOrCreateTypedArrayConstructor(JSContext* cx, Handle<GlobalObject*> global) { getOrCreateTypedArrayConstructor(JSContext* cx, Handle<GlobalObject*> global) {
if (!ensureConstructor(cx, global, JSProto_TypedArray)) if (!ensureConstructor(cx, global, JSProto_TypedArray))
@@ -831,6 +843,7 @@ class GlobalObject : public NativeObject
static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global); static bool initModuleProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global); static bool initImportEntryProto(JSContext* cx, Handle<GlobalObject*> global);
static bool initExportEntryProto(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 // Implemented in builtin/TypedObject.cpp
static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global); static bool initTypedObjectModule(JSContext* cx, Handle<GlobalObject*> global);