mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 930414 - Add module importEntries field r=shu
This commit is contained in:
parent
5592c607f8
commit
a62f1f731f
@ -6,10 +6,14 @@
|
||||
|
||||
#include "builtin/ModuleObject.h"
|
||||
|
||||
#include "gc/Tracer.h"
|
||||
|
||||
#include "jsobjinlines.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
typedef JS::Rooted<ImportEntryObject*> RootedImportEntry;
|
||||
|
||||
template<typename T, Value ValueGetter(T* obj)>
|
||||
static bool
|
||||
ModuleValueGetterImpl(JSContext* cx, CallArgs args)
|
||||
@ -38,6 +42,83 @@ ModuleValueGetter(JSContext* cx, unsigned argc, Value* vp)
|
||||
return ModuleValueGetter<cls, cls##_##name##Value>(cx, argc, vp); \
|
||||
}
|
||||
|
||||
#define DEFINE_ATOM_ACCESSOR_METHOD(cls, name) \
|
||||
JSAtom* \
|
||||
cls::name() \
|
||||
{ \
|
||||
Value value = cls##_##name##Value(this); \
|
||||
return &value.toString()->asAtom(); \
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ImportEntryObject
|
||||
|
||||
/* static */ const Class
|
||||
ImportEntryObject::class_ = {
|
||||
"ImportEntry",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ImportEntryObject::SlotCount) |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_ImportEntry) |
|
||||
JSCLASS_IS_ANONYMOUS |
|
||||
JSCLASS_IMPLEMENTS_BARRIERS
|
||||
};
|
||||
|
||||
DEFINE_GETTER_FUNCTIONS(ImportEntryObject, moduleRequest, ModuleRequestSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(ImportEntryObject, importName, ImportNameSlot)
|
||||
DEFINE_GETTER_FUNCTIONS(ImportEntryObject, localName, LocalNameSlot)
|
||||
|
||||
DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, moduleRequest)
|
||||
DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, importName)
|
||||
DEFINE_ATOM_ACCESSOR_METHOD(ImportEntryObject, localName)
|
||||
|
||||
/* static */ bool
|
||||
ImportEntryObject::isInstance(HandleValue value)
|
||||
{
|
||||
return value.isObject() && value.toObject().is<ImportEntryObject>();
|
||||
}
|
||||
|
||||
/* static */ JSObject*
|
||||
ImportEntryObject::initClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("moduleRequest", ImportEntryObject_moduleRequestGetter, 0),
|
||||
JS_PSG("importName", ImportEntryObject_importNameGetter, 0),
|
||||
JS_PSG("localName", ImportEntryObject_localNameGetter, 0),
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
Rooted<GlobalObject*> global(cx, &obj->as<GlobalObject>());
|
||||
RootedObject proto(cx, global->createBlankPrototype<PlainObject>(cx));
|
||||
if (!proto)
|
||||
return nullptr;
|
||||
|
||||
if (!DefinePropertiesAndFunctions(cx, proto, protoAccessors, nullptr))
|
||||
return nullptr;
|
||||
|
||||
global->setPrototype(JSProto_ImportEntry, ObjectValue(*proto));
|
||||
return proto;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
js::InitImportEntryClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
return ImportEntryObject::initClass(cx, obj);
|
||||
}
|
||||
|
||||
/* static */ ImportEntryObject*
|
||||
ImportEntryObject::create(JSContext* cx,
|
||||
HandleAtom moduleRequest,
|
||||
HandleAtom importName,
|
||||
HandleAtom localName)
|
||||
{
|
||||
RootedImportEntry self(cx, NewBuiltinClassInstance<ImportEntryObject>(cx));
|
||||
if (!self)
|
||||
return nullptr;
|
||||
self->initReservedSlot(ModuleRequestSlot, StringValue(moduleRequest));
|
||||
self->initReservedSlot(ImportNameSlot, StringValue(importName));
|
||||
self->initReservedSlot(LocalNameSlot, StringValue(localName));
|
||||
return self;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ModuleObject
|
||||
|
||||
@ -71,8 +152,7 @@ ModuleObject::class_ = {
|
||||
}
|
||||
|
||||
DEFINE_ARRAY_SLOT_ACCESSOR(ModuleObject, requestedModules, RequestedModulesSlot)
|
||||
|
||||
#undef DEFINE_ARRAY_SLOT_ACCESSOR
|
||||
DEFINE_ARRAY_SLOT_ACCESSOR(ModuleObject, importEntries, ImportEntriesSlot)
|
||||
|
||||
/* static */ bool
|
||||
ModuleObject::isInstance(HandleValue value)
|
||||
@ -93,9 +173,11 @@ ModuleObject::init(HandleScript script)
|
||||
}
|
||||
|
||||
void
|
||||
ModuleObject::initImportExportData(HandleArrayObject requestedModules)
|
||||
ModuleObject::initImportExportData(HandleArrayObject requestedModules,
|
||||
HandleArrayObject importEntries)
|
||||
{
|
||||
initReservedSlot(RequestedModulesSlot, ObjectValue(*requestedModules));
|
||||
initReservedSlot(ImportEntriesSlot, ObjectValue(*importEntries));
|
||||
}
|
||||
|
||||
JSScript*
|
||||
@ -114,14 +196,14 @@ ModuleObject::trace(JSTracer* trc, JSObject* obj)
|
||||
}
|
||||
|
||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, requestedModules, RequestedModulesSlot)
|
||||
|
||||
#undef DEFINE_GETTER_FUNCTIONS
|
||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, importEntries, ImportEntriesSlot)
|
||||
|
||||
JSObject*
|
||||
js::InitModuleClass(JSContext* cx, HandleObject obj)
|
||||
{
|
||||
static const JSPropertySpec protoAccessors[] = {
|
||||
JS_PSG("requestedModules", ModuleObject_requestedModulesGetter, 0),
|
||||
JS_PSG("importEntries", ModuleObject_importEntriesGetter, 0),
|
||||
JS_PS_END
|
||||
};
|
||||
|
||||
@ -138,12 +220,18 @@ js::InitModuleClass(JSContext* cx, HandleObject obj)
|
||||
return proto;
|
||||
}
|
||||
|
||||
#undef DEFINE_GETTER_FUNCTIONS
|
||||
#undef DEFINE_STRING_ACCESSOR_METHOD
|
||||
#undef DEFINE_ARRAY_SLOT_ACCESSOR
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ModuleBuilder
|
||||
|
||||
ModuleBuilder::ModuleBuilder(JSContext* cx)
|
||||
: cx_(cx),
|
||||
requestedModules_(cx, AtomVector(cx))
|
||||
requestedModules_(cx, AtomVector(cx)),
|
||||
importedBoundNames_(cx, AtomVector(cx)),
|
||||
importEntries_(cx, ImportEntryVector(cx))
|
||||
{}
|
||||
|
||||
bool
|
||||
@ -182,7 +270,13 @@ ModuleBuilder::buildAndInit(frontend::ParseNode* moduleNode, HandleModuleObject
|
||||
if (!requestedModules)
|
||||
return false;
|
||||
|
||||
module->initImportExportData(requestedModules);
|
||||
RootedArrayObject importEntries(cx_, createArray<ImportEntryObject*>(importEntries_));
|
||||
if (!importEntries)
|
||||
return false;
|
||||
|
||||
module->initImportExportData(requestedModules,
|
||||
importEntries);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -197,6 +291,28 @@ ModuleBuilder::processImport(frontend::ParseNode* pn)
|
||||
if (!maybeAppendRequestedModule(module))
|
||||
return false;
|
||||
|
||||
for (ParseNode* spec = pn->pn_left->pn_head; spec; spec = spec->pn_next) {
|
||||
MOZ_ASSERT(spec->isKind(PNK_IMPORT_SPEC));
|
||||
MOZ_ASSERT(spec->pn_left->isArity(PN_NAME));
|
||||
MOZ_ASSERT(spec->pn_right->isArity(PN_NAME));
|
||||
|
||||
RootedAtom importName(cx_, spec->pn_left->pn_atom);
|
||||
RootedAtom localName(cx_, spec->pn_right->pn_atom);
|
||||
|
||||
if (!importedBoundNames_.append(localName))
|
||||
return false;
|
||||
|
||||
RootedImportEntry importEntry(cx_);
|
||||
importEntry = ImportEntryObject::create(cx_, module, importName, localName);
|
||||
if (!importEntry)
|
||||
return false;
|
||||
|
||||
if (!importEntries_.append(importEntry)) {
|
||||
ReportOutOfMemory(cx_);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -229,6 +345,12 @@ MakeElementValue(JSString *string)
|
||||
return StringValue(string);
|
||||
}
|
||||
|
||||
static Value
|
||||
MakeElementValue(JSObject *object)
|
||||
{
|
||||
return ObjectValue(*object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ArrayObject* ModuleBuilder::createArray(const TraceableVector<T>& vector)
|
||||
{
|
||||
|
@ -19,6 +19,29 @@ namespace frontend {
|
||||
class ParseNode;
|
||||
} /* namespace frontend */
|
||||
|
||||
class ImportEntryObject : public NativeObject
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
ModuleRequestSlot = 0,
|
||||
ImportNameSlot,
|
||||
LocalNameSlot,
|
||||
SlotCount
|
||||
};
|
||||
|
||||
static const Class class_;
|
||||
static JSObject* initClass(JSContext* cx, HandleObject obj);
|
||||
static bool isInstance(HandleValue value);
|
||||
static ImportEntryObject* create(JSContext* cx,
|
||||
HandleAtom moduleRequest,
|
||||
HandleAtom importName,
|
||||
HandleAtom localName);
|
||||
JSAtom* moduleRequest();
|
||||
JSAtom* importName();
|
||||
JSAtom* localName();
|
||||
};
|
||||
|
||||
class ModuleObject : public NativeObject
|
||||
{
|
||||
public:
|
||||
@ -26,6 +49,7 @@ class ModuleObject : public NativeObject
|
||||
{
|
||||
ScriptSlot = 0,
|
||||
RequestedModulesSlot,
|
||||
ImportEntriesSlot,
|
||||
SlotCount
|
||||
};
|
||||
|
||||
@ -35,10 +59,12 @@ class ModuleObject : public NativeObject
|
||||
|
||||
static ModuleObject* create(ExclusiveContext* cx);
|
||||
void init(HandleScript script);
|
||||
void initImportExportData(HandleArrayObject requestedModules);
|
||||
void initImportExportData(HandleArrayObject requestedModules,
|
||||
HandleArrayObject importEntries);
|
||||
|
||||
JSScript* script() const;
|
||||
ArrayObject& requestedModules() const;
|
||||
ArrayObject& importEntries() const;
|
||||
|
||||
private:
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
@ -59,9 +85,13 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
private:
|
||||
using AtomVector = TraceableVector<JSAtom*>;
|
||||
using RootedAtomVector = JS::Rooted<AtomVector>;
|
||||
using ImportEntryVector = TraceableVector<ImportEntryObject*>;
|
||||
using RootedImportEntryVector = JS::Rooted<ImportEntryVector>;
|
||||
|
||||
JSContext* cx_;
|
||||
RootedAtomVector requestedModules_;
|
||||
RootedAtomVector importedBoundNames_;
|
||||
RootedImportEntryVector importEntries_;
|
||||
|
||||
bool processImport(frontend::ParseNode* pn);
|
||||
bool processExportFrom(frontend::ParseNode* pn);
|
||||
@ -73,6 +103,7 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||
};
|
||||
|
||||
JSObject* InitModuleClass(JSContext* cx, HandleObject obj);
|
||||
JSObject* InitImportEntryClass(JSContext* cx, HandleObject obj);
|
||||
|
||||
} // namespace js
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "jsgc.h"
|
||||
#include "jsprf.h"
|
||||
|
||||
#include "builtin/ModuleObject.h"
|
||||
#include "gc/GCInternals.h"
|
||||
#include "jit/IonCode.h"
|
||||
#include "js/SliceBudget.h"
|
||||
@ -369,6 +370,7 @@ AssertRootMarkingPhase(JSTracer* trc)
|
||||
D(ScriptSourceObject*) \
|
||||
D(SharedArrayBufferObject*) \
|
||||
D(SharedTypedArrayObject*) \
|
||||
D(ImportEntryObject*) \
|
||||
D(JSScript*) \
|
||||
D(LazyScript*) \
|
||||
D(Shape*) \
|
||||
|
33
js/src/jit-test/tests/modules/import-entries.js
Normal file
33
js/src/jit-test/tests/modules/import-entries.js
Normal file
@ -0,0 +1,33 @@
|
||||
// Test importEntries property
|
||||
|
||||
function testImportEntries(source, expected) {
|
||||
var module = parseModule(source);
|
||||
var actual = module.importEntries;
|
||||
assertEq(actual.length, expected.length);
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
for (var property in expected[i]) {
|
||||
assertEq(actual[i][property], expected[i][property]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
testImportEntries('', []);
|
||||
|
||||
testImportEntries('import v from "mod";',
|
||||
[{moduleRequest: 'mod', importName: 'default', localName: 'v'}]);
|
||||
|
||||
testImportEntries('import * as ns from "mod";',
|
||||
[{moduleRequest: 'mod', importName: '*', localName: 'ns'}]);
|
||||
|
||||
testImportEntries('import {x} from "mod";',
|
||||
[{moduleRequest: 'mod', importName: 'x', localName: 'x'}]);
|
||||
|
||||
testImportEntries('import {x as v} from "mod";',
|
||||
[{moduleRequest: 'mod', importName: 'x', localName: 'v'}]);
|
||||
|
||||
testImportEntries('import "mod";',
|
||||
[]);
|
||||
|
||||
testImportEntries('import {x} from "a"; import {y} from "b";',
|
||||
[{moduleRequest: 'a', importName: 'x', localName: 'x'},
|
||||
{moduleRequest: 'b', importName: 'y', localName: 'y'}]);
|
@ -114,6 +114,7 @@ IF_SAB(real,imaginary)(Atomics, 53, InitAtomicsClass, OCLASP
|
||||
real(SavedFrame, 54, InitViaClassSpec, &js::SavedFrame::class_) \
|
||||
real(Reflect, 55, InitReflect, nullptr) \
|
||||
real(Module, 56, InitModuleClass, OCLASP(Module)) \
|
||||
real(ImportEntry, 57, InitImportEntryClass, OCLASP(ImportEntry)) \
|
||||
|
||||
#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user