mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-29 10:37:33 +09:00
Issue #1691 - Part 4: Finish implementing call import. https://bugzilla.mozilla.org/show_bug.cgi?id=1499140
(cherry picked from commit 7bf7d64887944b127a72090dd62eb57f67c5089d)
This commit is contained in:
parent
3f4985ce6c
commit
7a6dab0b38
35 changed files with 533 additions and 24 deletions
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "builtin/ModuleObject.h"
|
#include "builtin/ModuleObject.h"
|
||||||
|
|
||||||
|
#include "builtin/Promise.h"
|
||||||
#include "builtin/SelfHostingDefines.h"
|
#include "builtin/SelfHostingDefines.h"
|
||||||
#include "frontend/ParseNode.h"
|
#include "frontend/ParseNode.h"
|
||||||
#include "frontend/SharedContext.h"
|
#include "frontend/SharedContext.h"
|
||||||
|
|
@ -1030,6 +1031,22 @@ ModuleObject::Evaluate(JSContext* cx, HandleModuleObject self)
|
||||||
return InvokeSelfHostedMethod(cx, self, cx->names().ModuleEvaluate);
|
return InvokeSelfHostedMethod(cx, self, cx->names().ModuleEvaluate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ ModuleNamespaceObject*
|
||||||
|
ModuleObject::GetOrCreateModuleNamespace(JSContext* cx, HandleModuleObject self)
|
||||||
|
{
|
||||||
|
FixedInvokeArgs<1> args(cx);
|
||||||
|
args[0].setObject(*self);
|
||||||
|
|
||||||
|
RootedValue result(cx);
|
||||||
|
if (!CallSelfHostedFunction(cx, cx->names().GetModuleNamespace, UndefinedHandleValue, args,
|
||||||
|
&result))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &result.toObject().as<ModuleNamespaceObject>();
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, namespace_, NamespaceSlot)
|
DEFINE_GETTER_FUNCTIONS(ModuleObject, namespace_, NamespaceSlot)
|
||||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, status, StatusSlot)
|
DEFINE_GETTER_FUNCTIONS(ModuleObject, status, StatusSlot)
|
||||||
DEFINE_GETTER_FUNCTIONS(ModuleObject, evaluationError, EvaluationErrorSlot)
|
DEFINE_GETTER_FUNCTIONS(ModuleObject, evaluationError, EvaluationErrorSlot)
|
||||||
|
|
@ -1519,3 +1536,88 @@ js::GetOrCreateModuleMetaObject(JSContext* cx, HandleObject moduleArg)
|
||||||
|
|
||||||
return metaObject;
|
return metaObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
js::CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
|
||||||
|
{
|
||||||
|
JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
|
||||||
|
if (!moduleResolveHook) {
|
||||||
|
JS_ReportErrorASCII(cx, "Module resolve hook not set");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedObject result(cx, moduleResolveHook(cx, referencingPrivate, specifier));
|
||||||
|
if (!result) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result->is<ModuleObject>()) {
|
||||||
|
JS_ReportErrorASCII(cx, "Module resolve hook did not return Module object");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
js::StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifierArg)
|
||||||
|
{
|
||||||
|
RootedObject promiseConstructor(cx, JS::GetPromiseConstructor(cx));
|
||||||
|
if (!promiseConstructor) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedObject promiseObject(cx, JS::NewPromiseObject(cx, nullptr));
|
||||||
|
if (!promiseObject) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<PromiseObject*> promise = promiseObject.as<PromiseObject>();
|
||||||
|
|
||||||
|
RootedString specifier(cx, ToString(cx, specifierArg));
|
||||||
|
if (!specifier) {
|
||||||
|
if (!RejectPromiseWithPendingError(cx, promise))
|
||||||
|
return nullptr;
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::ModuleDynamicImportHook importHook = cx->runtime()->moduleDynamicImportHook;
|
||||||
|
MOZ_ASSERT(importHook);
|
||||||
|
if (!importHook(cx, referencingPrivate, specifier, promise)) {
|
||||||
|
if (!RejectPromiseWithPendingError(cx, promise))
|
||||||
|
return nullptr;
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
|
||||||
|
HandleObject promiseArg)
|
||||||
|
{
|
||||||
|
Handle<PromiseObject*> promise = promiseArg.as<PromiseObject>();
|
||||||
|
|
||||||
|
if (cx->isExceptionPending()) {
|
||||||
|
return RejectPromiseWithPendingError(cx, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedObject result(cx, CallModuleResolveHook(cx, referencingPrivate, specifier));
|
||||||
|
if (!result) {
|
||||||
|
return RejectPromiseWithPendingError(cx, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedModuleObject module(cx, &result->as<ModuleObject>());
|
||||||
|
if (module->status() != MODULE_STATUS_EVALUATED) {
|
||||||
|
JS_ReportErrorASCII(cx, "Unevaluated or errored module returned by module resolve hook");
|
||||||
|
return RejectPromiseWithPendingError(cx, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedObject ns(cx, ModuleObject::GetOrCreateModuleNamespace(cx, module));
|
||||||
|
if (!ns) {
|
||||||
|
return RejectPromiseWithPendingError(cx, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedValue value(cx, ObjectValue(*ns));
|
||||||
|
return PromiseObject::resolve(cx, promise, value);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,9 @@ class ModuleObject : public NativeObject
|
||||||
static bool Instantiate(JSContext* cx, HandleModuleObject self);
|
static bool Instantiate(JSContext* cx, HandleModuleObject self);
|
||||||
static bool Evaluate(JSContext* cx, HandleModuleObject self);
|
static bool Evaluate(JSContext* cx, HandleModuleObject self);
|
||||||
|
|
||||||
|
static ModuleNamespaceObject* GetOrCreateModuleNamespace(JSContext* cx,
|
||||||
|
HandleModuleObject self);
|
||||||
|
|
||||||
void setMetaObject(JSObject* obj);
|
void setMetaObject(JSObject* obj);
|
||||||
|
|
||||||
// For BytecodeEmitter.
|
// For BytecodeEmitter.
|
||||||
|
|
@ -374,6 +377,16 @@ class MOZ_STACK_CLASS ModuleBuilder
|
||||||
JSObject*
|
JSObject*
|
||||||
GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module);
|
GetOrCreateModuleMetaObject(JSContext* cx, HandleObject module);
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier);
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
StartDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleValue specifier);
|
||||||
|
|
||||||
|
bool
|
||||||
|
FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
|
||||||
|
HandleObject promise);
|
||||||
|
|
||||||
} // namespace js
|
} // namespace js
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
|
||||||
|
|
@ -3863,6 +3863,16 @@ OriginalPromiseThenBuiltin(JSContext* cx, HandleValue promiseVal, HandleValue on
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_MUST_USE bool
|
||||||
|
js::RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise)
|
||||||
|
{
|
||||||
|
// Not much we can do about uncatchable exceptions, just bail.
|
||||||
|
RootedValue exn(cx);
|
||||||
|
if (!GetAndClearException(cx, &exn))
|
||||||
|
return false;
|
||||||
|
return PromiseObject::reject(cx, promise, exn);
|
||||||
|
}
|
||||||
|
|
||||||
static MOZ_MUST_USE bool PerformPromiseThenWithReaction(JSContext* cx,
|
static MOZ_MUST_USE bool PerformPromiseThenWithReaction(JSContext* cx,
|
||||||
Handle<PromiseObject*> promise,
|
Handle<PromiseObject*> promise,
|
||||||
Handle<PromiseReactionRecord*> reaction);
|
Handle<PromiseReactionRecord*> reaction);
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,9 @@ OriginalPromiseThen(JSContext* cx, Handle<PromiseObject*> promise,
|
||||||
MOZ_MUST_USE JSObject*
|
MOZ_MUST_USE JSObject*
|
||||||
PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
|
PromiseResolve(JSContext* cx, HandleObject constructor, HandleValue value);
|
||||||
|
|
||||||
|
MOZ_MUST_USE bool
|
||||||
|
RejectPromiseWithPendingError(JSContext* cx, Handle<PromiseObject*> promise);
|
||||||
|
|
||||||
MOZ_MUST_USE PromiseObject*
|
MOZ_MUST_USE PromiseObject*
|
||||||
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
|
CreatePromiseObjectForAsync(JSContext* cx, HandleValue generatorVal);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9088,8 +9088,14 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PNK_CALL_IMPORT:
|
case PNK_CALL_IMPORT:
|
||||||
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
|
if (!cx->asJSContext()->runtime()->moduleDynamicImportHook) {
|
||||||
return false;
|
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!emitTree(pn->as<BinaryNode>().right()) || !emit1(JSOP_DYNAMIC_IMPORT)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case PNK_SETTHIS:
|
case PNK_SETTHIS:
|
||||||
if (!emitSetThis(&pn->as<BinaryNode>()))
|
if (!emitSetThis(&pn->as<BinaryNode>()))
|
||||||
|
|
|
||||||
|
|
@ -595,7 +595,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryNodeType newCallImport(Node importHolder, Node singleArg) {
|
BinaryNodeType newCallImport(Node importHolder, Node singleArg) {
|
||||||
return new_<BinaryNode>(PNK_CALL_IMPORT, JSOP_NOP, importHolder, singleArg);
|
return new_<BinaryNode>(PNK_CALL_IMPORT, JSOP_DYNAMIC_IMPORT, importHolder, singleArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnaryNodeType newExprStatement(Node expr, uint32_t end) {
|
UnaryNodeType newExprStatement(Node expr, uint32_t end) {
|
||||||
|
|
|
||||||
|
|
@ -837,7 +837,6 @@ class NameResolver
|
||||||
|
|
||||||
case PNK_CALL_IMPORT: {
|
case PNK_CALL_IMPORT: {
|
||||||
BinaryNode* node = &cur->as<BinaryNode>();
|
BinaryNode* node = &cur->as<BinaryNode>();
|
||||||
MOZ_ASSERT(cur->isArity(PN_BINARY));
|
|
||||||
if (!resolve(node->right(), prefix))
|
if (!resolve(node->right(), prefix))
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -541,6 +541,8 @@ IsTypeofKind(ParseNodeKind kind)
|
||||||
* PNK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP
|
* PNK_ARRAYPUSH unary pn_op: JSOP_ARRAYCOMP
|
||||||
* pn_kid: array comprehension expression
|
* pn_kid: array comprehension expression
|
||||||
* PNK_NOP (NullaryNode)
|
* PNK_NOP (NullaryNode)
|
||||||
|
* PNK_IMPORT_META (BinaryNode)
|
||||||
|
* PNK_CALL_IMPORT (BinaryNode)
|
||||||
*/
|
*/
|
||||||
enum ParseNodeArity
|
enum ParseNodeArity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10515,6 +10515,10 @@ Parser<ParseHandler>::importExpr(YieldHandling yieldHandling)
|
||||||
|
|
||||||
MUST_MATCH_TOKEN_MOD(TOK_RP, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
|
MUST_MATCH_TOKEN_MOD(TOK_RP, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
|
||||||
|
|
||||||
|
if (!context->asJSContext()->runtime()->moduleDynamicImportHook && !abortIfSyntaxParser()) {
|
||||||
|
return null();
|
||||||
|
}
|
||||||
|
|
||||||
return handler.newCallImport(importHolder, arg);
|
return handler.newCallImport(importHolder, arg);
|
||||||
} else {
|
} else {
|
||||||
error(JSMSG_UNEXPECTED_TOKEN, TokenKindToDesc(next));
|
error(JSMSG_UNEXPECTED_TOKEN, TokenKindToDesc(next));
|
||||||
|
|
|
||||||
|
|
@ -4708,3 +4708,28 @@ BaselineCompiler::emit_JSOP_IMPORTMETA()
|
||||||
frame.push(ObjectValue(*metaObject));
|
frame.push(ObjectValue(*metaObject));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
|
||||||
|
static const VMFunction StartDynamicModuleImportInfo =
|
||||||
|
FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
|
||||||
|
"StartDynamicModuleImport");
|
||||||
|
|
||||||
|
bool
|
||||||
|
BaselineCompiler::emit_JSOP_DYNAMIC_IMPORT()
|
||||||
|
{
|
||||||
|
RootedValue referencingPrivate(cx, FindScriptOrModulePrivateForScript(script));
|
||||||
|
|
||||||
|
// Put specifier value in R0.
|
||||||
|
frame.popRegsAndSync(1);
|
||||||
|
|
||||||
|
prepareVMCall();
|
||||||
|
pushArg(R0);
|
||||||
|
pushArg(referencingPrivate);
|
||||||
|
if (!callVM(StartDynamicModuleImportInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
masm.tagValue(JSVAL_TYPE_OBJECT, ReturnReg, R0);
|
||||||
|
frame.push(R0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,8 @@ namespace jit {
|
||||||
_(JSOP_JUMPTARGET) \
|
_(JSOP_JUMPTARGET) \
|
||||||
_(JSOP_IS_CONSTRUCTING) \
|
_(JSOP_IS_CONSTRUCTING) \
|
||||||
_(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
|
_(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
|
||||||
_(JSOP_IMPORTMETA)
|
_(JSOP_IMPORTMETA) \
|
||||||
|
_(JSOP_DYNAMIC_IMPORT)
|
||||||
|
|
||||||
class BaselineCompiler : public BaselineCompilerSpecific
|
class BaselineCompiler : public BaselineCompilerSpecific
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2402,6 +2402,19 @@ CodeGenerator::visitNullarySharedStub(LNullarySharedStub* lir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef JSObject* (*StartDynamicModuleImportFn)(JSContext*, HandleValue, HandleValue);
|
||||||
|
static const VMFunction StartDynamicModuleImportInfo =
|
||||||
|
FunctionInfo<StartDynamicModuleImportFn>(js::StartDynamicModuleImport,
|
||||||
|
"StartDynamicModuleImport");
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeGenerator::visitDynamicImport(LDynamicImport* lir)
|
||||||
|
{
|
||||||
|
pushArg(ToValue(lir, LDynamicImport::SpecifierIndex));
|
||||||
|
pushArg(ToValue(lir, LDynamicImport::ReferencingPrivateIndex));
|
||||||
|
callVM(StartDynamicModuleImportInfo, lir);
|
||||||
|
}
|
||||||
|
|
||||||
typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject);
|
typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject);
|
||||||
static const VMFunction LambdaInfo = FunctionInfo<LambdaFn>(js::Lambda, "Lambda");
|
static const VMFunction LambdaInfo = FunctionInfo<LambdaFn>(js::Lambda, "Lambda");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
||||||
|
|
||||||
void visitRandom(LRandom* ins);
|
void visitRandom(LRandom* ins);
|
||||||
void visitSignExtend(LSignExtend* ins);
|
void visitSignExtend(LSignExtend* ins);
|
||||||
|
void visitDynamicImport(LDynamicImport* lir);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void emitDebugForceBailing(LInstruction* lir);
|
void emitDebugForceBailing(LInstruction* lir);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "jit/Lowering.h"
|
#include "jit/Lowering.h"
|
||||||
#include "jit/MIRGraph.h"
|
#include "jit/MIRGraph.h"
|
||||||
#include "vm/ArgumentsObject.h"
|
#include "vm/ArgumentsObject.h"
|
||||||
|
#include "vm/EnvironmentObject.h"
|
||||||
#include "vm/Opcodes.h"
|
#include "vm/Opcodes.h"
|
||||||
#include "vm/RegExpStatics.h"
|
#include "vm/RegExpStatics.h"
|
||||||
#include "vm/TraceLogging.h"
|
#include "vm/TraceLogging.h"
|
||||||
|
|
@ -2208,6 +2209,9 @@ IonBuilder::inspectOpcode(JSOp op)
|
||||||
case JSOP_IMPORTMETA:
|
case JSOP_IMPORTMETA:
|
||||||
return jsop_importmeta();
|
return jsop_importmeta();
|
||||||
|
|
||||||
|
case JSOP_DYNAMIC_IMPORT:
|
||||||
|
return jsop_dynamic_import();
|
||||||
|
|
||||||
case JSOP_DEBUGCHECKSELFHOSTED:
|
case JSOP_DEBUGCHECKSELFHOSTED:
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -14264,6 +14268,20 @@ IonBuilder::jsop_importmeta()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IonBuilder::jsop_dynamic_import()
|
||||||
|
{
|
||||||
|
Value referencingPrivate = FindScriptOrModulePrivateForScript(script());
|
||||||
|
MConstant* ref = constant(referencingPrivate);
|
||||||
|
|
||||||
|
MDefinition* specifier = current->pop();
|
||||||
|
|
||||||
|
MDynamicImport* ins = MDynamicImport::New(alloc(), ref, specifier);
|
||||||
|
current->add(ins);
|
||||||
|
current->push(ins);
|
||||||
|
return resumeAfter(ins);
|
||||||
|
}
|
||||||
|
|
||||||
MInstruction*
|
MInstruction*
|
||||||
IonBuilder::addConvertElementsToDoubles(MDefinition* elements)
|
IonBuilder::addConvertElementsToDoubles(MDefinition* elements)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -789,6 +789,7 @@ class IonBuilder
|
||||||
MOZ_MUST_USE bool jsop_checkobjcoercible();
|
MOZ_MUST_USE bool jsop_checkobjcoercible();
|
||||||
MOZ_MUST_USE bool jsop_pushcallobj();
|
MOZ_MUST_USE bool jsop_pushcallobj();
|
||||||
MOZ_MUST_USE bool jsop_importmeta();
|
MOZ_MUST_USE bool jsop_importmeta();
|
||||||
|
MOZ_MUST_USE bool jsop_dynamic_import();
|
||||||
|
|
||||||
/* Inlining. */
|
/* Inlining. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2427,6 +2427,15 @@ LIRGenerator::visitNullarySharedStub(MNullarySharedStub* ins)
|
||||||
assignSafepoint(lir, ins);
|
assignSafepoint(lir, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LIRGenerator::visitDynamicImport(MDynamicImport* ins)
|
||||||
|
{
|
||||||
|
LDynamicImport* lir = new(alloc()) LDynamicImport(useBoxAtStart(ins->referencingPrivate()),
|
||||||
|
useBoxAtStart(ins->specifier()));
|
||||||
|
defineReturn(lir, ins);
|
||||||
|
assignSafepoint(lir, ins);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LIRGenerator::visitLambda(MLambda* ins)
|
LIRGenerator::visitLambda(MLambda* ins)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -334,6 +334,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||||
void visitCheckIsCallable(MCheckIsCallable* ins);
|
void visitCheckIsCallable(MCheckIsCallable* ins);
|
||||||
void visitCheckObjCoercible(MCheckObjCoercible* ins);
|
void visitCheckObjCoercible(MCheckObjCoercible* ins);
|
||||||
void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins);
|
void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins);
|
||||||
|
void visitDynamicImport(MDynamicImport* ins);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace jit
|
} // namespace jit
|
||||||
|
|
|
||||||
|
|
@ -8379,6 +8379,22 @@ class MSubstr
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MDynamicImport : public MBinaryInstruction,
|
||||||
|
public BoxInputsPolicy::Data
|
||||||
|
{
|
||||||
|
explicit MDynamicImport(MDefinition* referencingPrivate, MDefinition* specifier)
|
||||||
|
: MBinaryInstruction(referencingPrivate, specifier)
|
||||||
|
{
|
||||||
|
setResultType(MIRType::Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
INSTRUCTION_HEADER(DynamicImport)
|
||||||
|
TRIVIAL_NEW_WRAPPERS
|
||||||
|
NAMED_OPERANDS((0, referencingPrivate))
|
||||||
|
NAMED_OPERANDS((1, specifier))
|
||||||
|
};
|
||||||
|
|
||||||
struct LambdaFunctionInfo
|
struct LambdaFunctionInfo
|
||||||
{
|
{
|
||||||
// The functions used in lambdas are the canonical original function in
|
// The functions used in lambdas are the canonical original function in
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,7 @@ namespace jit {
|
||||||
_(GlobalNameConflictsCheck) \
|
_(GlobalNameConflictsCheck) \
|
||||||
_(Debugger) \
|
_(Debugger) \
|
||||||
_(NewTarget) \
|
_(NewTarget) \
|
||||||
|
_(DynamicImport) \
|
||||||
_(ArrowNewTarget) \
|
_(ArrowNewTarget) \
|
||||||
_(CheckReturn) \
|
_(CheckReturn) \
|
||||||
_(CheckIsObj) \
|
_(CheckIsObj) \
|
||||||
|
|
|
||||||
|
|
@ -4939,6 +4939,26 @@ class LNullarySharedStub : public LCallInstructionHelper<BOX_PIECES, 0, 0>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LDynamicImport : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIR_HEADER(DynamicImport)
|
||||||
|
|
||||||
|
static const size_t ReferencingPrivateIndex = 0;
|
||||||
|
static const size_t SpecifierIndex = BOX_PIECES;
|
||||||
|
|
||||||
|
explicit LDynamicImport(const LBoxAllocation& referencingPrivate,
|
||||||
|
const LBoxAllocation& specifier)
|
||||||
|
{
|
||||||
|
setBoxOperand(ReferencingPrivateIndex, referencingPrivate);
|
||||||
|
setBoxOperand(SpecifierIndex, specifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
const MDynamicImport* mir() const {
|
||||||
|
return mir_->toDynamicImport();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
|
class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -401,6 +401,7 @@
|
||||||
_(GlobalNameConflictsCheck) \
|
_(GlobalNameConflictsCheck) \
|
||||||
_(Debugger) \
|
_(Debugger) \
|
||||||
_(NewTarget) \
|
_(NewTarget) \
|
||||||
|
_(DynamicImport) \
|
||||||
_(ArrowNewTarget) \
|
_(ArrowNewTarget) \
|
||||||
_(CheckReturn) \
|
_(CheckReturn) \
|
||||||
_(CheckIsObj) \
|
_(CheckIsObj) \
|
||||||
|
|
|
||||||
|
|
@ -592,6 +592,7 @@ MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found f
|
||||||
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
|
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
|
||||||
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
|
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
|
||||||
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
|
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
|
||||||
|
MSG_DEF(JSMSG_IMPORT_SCRIPT_NOT_FOUND, 0, JSEXN_TYPEERR, "can't find referencing script for dynamic module import")
|
||||||
|
|
||||||
// Promise
|
// Promise
|
||||||
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")
|
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")
|
||||||
|
|
|
||||||
|
|
@ -4712,6 +4712,29 @@ JS::SetModuleMetadataHook(JSContext* cx, JS::ModuleMetadataHook func)
|
||||||
cx->runtime()->moduleMetadataHook = func;
|
cx->runtime()->moduleMetadataHook = func;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(JS::ModuleDynamicImportHook)
|
||||||
|
JS::GetModuleDynamicImportHook(JSContext* cx)
|
||||||
|
{
|
||||||
|
AssertHeapIsIdle(cx);
|
||||||
|
return cx->runtime()->moduleDynamicImportHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(void)
|
||||||
|
JS::SetModuleDynamicImportHook(JSContext* cx, JS::ModuleDynamicImportHook func)
|
||||||
|
{
|
||||||
|
AssertHeapIsIdle(cx);
|
||||||
|
cx->runtime()->moduleDynamicImportHook = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_PUBLIC_API(bool)
|
||||||
|
JS::FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
|
||||||
|
HandleObject promise)
|
||||||
|
{
|
||||||
|
AssertHeapIsIdle(cx);
|
||||||
|
|
||||||
|
return js::FinishDynamicModuleImport(cx, referencingPrivate, specifier, promise);
|
||||||
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(bool)
|
JS_PUBLIC_API(bool)
|
||||||
JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||||
SourceBufferHolder& srcBuf, JS::MutableHandleObject module)
|
SourceBufferHolder& srcBuf, JS::MutableHandleObject module)
|
||||||
|
|
|
||||||
|
|
@ -4353,6 +4353,25 @@ GetModuleMetadataHook(JSContext* cx);
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
SetModuleMetadataHook(JSContext* cx, ModuleMetadataHook func);
|
SetModuleMetadataHook(JSContext* cx, ModuleMetadataHook func);
|
||||||
|
|
||||||
|
using ModuleDynamicImportHook = bool (*)(JSContext* cx, HandleValue referencingPrivate,
|
||||||
|
HandleString specifier, HandleObject promise);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the HostResolveImportedModule hook for the runtime.
|
||||||
|
*/
|
||||||
|
extern JS_PUBLIC_API(ModuleDynamicImportHook)
|
||||||
|
GetModuleDynamicImportHook(JSContext* cx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the HostResolveImportedModule hook for the runtime to the given function.
|
||||||
|
*/
|
||||||
|
extern JS_PUBLIC_API(void)
|
||||||
|
SetModuleDynamicImportHook(JSContext* cx, ModuleDynamicImportHook func);
|
||||||
|
|
||||||
|
extern JS_PUBLIC_API(bool)
|
||||||
|
FinishDynamicModuleImport(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
|
||||||
|
HandleObject promise);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the given source buffer as a module in the scope of the current global
|
* Parse the given source buffer as a module in the scope of the current global
|
||||||
* of cx and return a source text module record.
|
* of cx and return a source text module record.
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,28 @@ Reflect.Loader = new class {
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
["import"](name, referrer) {
|
["import"](name, referencingInfo) {
|
||||||
let module = this.loadAndParse(name);
|
let module = this.loadAndParse(name);
|
||||||
module.declarationInstantiation();
|
module.declarationInstantiation();
|
||||||
return module.evaluation();
|
return module.evaluation();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
setModuleResolveHook((module, requestName) => Reflect.Loader.loadAndParse(requestName));
|
setModuleResolveHook((referencingInfo, requestName) => {
|
||||||
|
let path = ReflectLoader.resolve(requestName, referencingInfo);
|
||||||
|
return ReflectLoader.loadAndParse(path);
|
||||||
|
});
|
||||||
|
|
||||||
|
setModuleMetadataHook((module, metaObject) => {
|
||||||
|
ReflectLoader.populateImportMeta(module, metaObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
setModuleDynamicImportHook((referencingInfo, specifier, promise) => {
|
||||||
|
try {
|
||||||
|
let path = ReflectLoader.resolve(specifier, referencingInfo);
|
||||||
|
ReflectLoader.loadAndExecute(path);
|
||||||
|
finishDynamicModuleImport(referencingInfo, specifier, promise);
|
||||||
|
} catch (err) {
|
||||||
|
abortDynamicModuleImport(referencingInfo, specifier, promise, err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -603,6 +603,32 @@ EnvironmentPreparer::invoke(HandleObject scope, Closure& closure)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
RegisterScriptPathWithModuleLoader(JSContext* cx, HandleScript script, const char* filename)
|
||||||
|
{
|
||||||
|
// Set the private value associated with a script to a object containing the
|
||||||
|
// script's filename so that the module loader can use it to resolve
|
||||||
|
// relative imports.
|
||||||
|
|
||||||
|
RootedString path(cx, JS_NewStringCopyZ(cx, filename));
|
||||||
|
if (!path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedObject infoObject(cx, JS_NewPlainObject(cx));
|
||||||
|
if (!infoObject) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedValue pathValue(cx, StringValue(path));
|
||||||
|
if (!JS_DefineProperty(cx, infoObject, "path", pathValue, 0)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JS::SetScriptPrivate(script, ObjectValue(*infoObject));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static MOZ_MUST_USE bool
|
static MOZ_MUST_USE bool
|
||||||
RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
|
RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
|
||||||
{
|
{
|
||||||
|
|
@ -635,6 +661,10 @@ RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
|
||||||
MOZ_ASSERT(script);
|
MOZ_ASSERT(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!RegisterScriptPathWithModuleLoader(cx, script, filename)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
if (dumpEntrainedVariables)
|
if (dumpEntrainedVariables)
|
||||||
AnalyzeEntrainedVariables(cx, script);
|
AnalyzeEntrainedVariables(cx, script);
|
||||||
|
|
@ -4035,7 +4065,7 @@ SetModuleResolveHook(JSContext* cx, unsigned argc, Value* vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSObject*
|
static JSObject*
|
||||||
CallModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
|
ShellModuleResolveHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier)
|
||||||
{
|
{
|
||||||
ShellContext* sc = GetShellContext(cx);
|
ShellContext* sc = GetShellContext(cx);
|
||||||
|
|
||||||
|
|
@ -4119,6 +4149,109 @@ ShellModuleMetadataHook(JSContext* cx, HandleObject module, HandleObject metaObj
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
SetModuleDynamicImportHook(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
if (args.length() != 1) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||||
|
"setModuleDynamicImportHook", "0", "s");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
|
||||||
|
const char* typeName = InformalValueTypeName(args[0]);
|
||||||
|
JS_ReportErrorASCII(cx, "expected hook function, got %s", typeName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle<GlobalObject*> global = cx->global();
|
||||||
|
global->setReservedSlot(GlobalAppSlotModuleDynamicImportHook, args[0]);
|
||||||
|
|
||||||
|
args.rval().setUndefined();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
FinishDynamicModuleImport(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
if (args.length() != 3) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||||
|
"finishDynamicModuleImport", "0", "s");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[1].isString()) {
|
||||||
|
return ReportArgumentTypeError(cx, args[1], "String");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[2].isObject() || !args[2].toObject().is<PromiseObject>()) {
|
||||||
|
return ReportArgumentTypeError(cx, args[2], "PromiseObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedString specifier(cx, args[1].toString());
|
||||||
|
Rooted<PromiseObject*> promise(cx, &args[2].toObject().as<PromiseObject>());
|
||||||
|
|
||||||
|
return js::FinishDynamicModuleImport(cx, args[0], specifier, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AbortDynamicModuleImport(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
if (args.length() != 4) {
|
||||||
|
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED,
|
||||||
|
"abortDynamicModuleImport", "0", "s");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[1].isString()) {
|
||||||
|
return ReportArgumentTypeError(cx, args[1], "String");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[2].isObject() || !args[2].toObject().is<PromiseObject>()) {
|
||||||
|
return ReportArgumentTypeError(cx, args[2], "PromiseObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!args[3].isObject() || !args[3].toObject().is<ErrorObject>()) {
|
||||||
|
return ReportArgumentTypeError(cx, args[3], "ErrorObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
RootedString specifier(cx, args[1].toString());
|
||||||
|
Rooted<PromiseObject*> promise(cx, &args[2].toObject().as<PromiseObject>());
|
||||||
|
Rooted<ErrorObject*> error(cx, &args[3].toObject().as<ErrorObject>());
|
||||||
|
|
||||||
|
Rooted<Value> value(cx, ObjectValue(*error));
|
||||||
|
cx->setPendingException(value);
|
||||||
|
return js::FinishDynamicModuleImport(cx, args[0], specifier, promise);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
ShellModuleDynamicImportHook(JSContext* cx, HandleValue referencingPrivate, HandleString specifier,
|
||||||
|
HandleObject promise)
|
||||||
|
{
|
||||||
|
Handle<GlobalObject*> global = cx->global();
|
||||||
|
RootedValue hookValue(cx, global->getReservedSlot(GlobalAppSlotModuleDynamicImportHook));
|
||||||
|
if (hookValue.isUndefined()) {
|
||||||
|
JS_ReportErrorASCII(cx, "Module resolve hook not set");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(hookValue.toObject().is<JSFunction>());
|
||||||
|
|
||||||
|
JS::AutoValueArray<3> args(cx);
|
||||||
|
args[0].set(referencingPrivate);
|
||||||
|
args[1].setString(specifier);
|
||||||
|
args[2].setObject(*promise);
|
||||||
|
|
||||||
|
RootedValue result(cx);
|
||||||
|
if (!JS_CallFunctionValue(cx, nullptr, hookValue, args, &result)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
GetModuleLoadPath(JSContext* cx, unsigned argc, Value* vp)
|
||||||
{
|
{
|
||||||
|
|
@ -5984,7 +6117,7 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||||
" Parses source text as a module and returns a Module object."),
|
" Parses source text as a module and returns a Module object."),
|
||||||
|
|
||||||
JS_FN_HELP("setModuleResolveHook", SetModuleResolveHook, 1, 0,
|
JS_FN_HELP("setModuleResolveHook", SetModuleResolveHook, 1, 0,
|
||||||
"setModuleResolveHook(function(module, specifier) {})",
|
"setModuleResolveHook(function(referrer, specifier))",
|
||||||
" Set the HostResolveImportedModule hook to |function|.\n"
|
" Set the HostResolveImportedModule hook to |function|.\n"
|
||||||
" This hook is used to look up a previously loaded module object. It should\n"
|
" This hook is used to look up a previously loaded module object. It should\n"
|
||||||
" be implemented by the module loader."),
|
" be implemented by the module loader."),
|
||||||
|
|
@ -5997,6 +6130,28 @@ static const JSFunctionSpecWithHelp shell_functions[] = {
|
||||||
"getModulePrivate(scriptObject)",
|
"getModulePrivate(scriptObject)",
|
||||||
" Get the private value associated with a module object.\n"),
|
" Get the private value associated with a module object.\n"),
|
||||||
|
|
||||||
|
JS_FN_HELP("setModuleMetadataHook", SetModuleMetadataHook, 1, 0,
|
||||||
|
"setModuleMetadataHook(function(module) {})",
|
||||||
|
" Set the HostPopulateImportMeta hook to |function|.\n"
|
||||||
|
" This hook is used to create the metadata object returned by import.meta for\n"
|
||||||
|
" a module. It should be implemented by the module loader."),
|
||||||
|
|
||||||
|
JS_FN_HELP("setModuleDynamicImportHook", SetModuleDynamicImportHook, 1, 0,
|
||||||
|
"setModuleDynamicImportHook(function(referrer, specifier, promise))",
|
||||||
|
" Set the HostImportModuleDynamically hook to |function|.\n"
|
||||||
|
" This hook is used to dynamically import a module. It should\n"
|
||||||
|
" be implemented by the module loader."),
|
||||||
|
|
||||||
|
JS_FN_HELP("finishDynamicModuleImport", FinishDynamicModuleImport, 3, 0,
|
||||||
|
"finishDynamicModuleImport(referrer, specifier, promise)",
|
||||||
|
" The module loader's dynamic import hook should call this when the module has"
|
||||||
|
" been loaded successfully."),
|
||||||
|
|
||||||
|
JS_FN_HELP("abortDynamicModuleImport", AbortDynamicModuleImport, 4, 0,
|
||||||
|
"abortDynamicModuleImport(referrer, specifier, promise, error)",
|
||||||
|
" The module loader's dynamic import hook should call this when the module "
|
||||||
|
" import has failed."),
|
||||||
|
|
||||||
JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
|
JS_FN_HELP("getModuleLoadPath", GetModuleLoadPath, 0, 0,
|
||||||
"getModuleLoadPath()",
|
"getModuleLoadPath()",
|
||||||
" Return any --module-load-path argument passed to the shell. Used by the\n"
|
" Return any --module-load-path argument passed to the shell. Used by the\n"
|
||||||
|
|
@ -8054,7 +8209,8 @@ main(int argc, char** argv, char** envp)
|
||||||
|
|
||||||
js::SetPreserveWrapperCallback(cx, DummyPreserveWrapperCallback);
|
js::SetPreserveWrapperCallback(cx, DummyPreserveWrapperCallback);
|
||||||
|
|
||||||
JS::SetModuleResolveHook(cx->runtime(), CallModuleResolveHook);
|
JS::SetModuleResolveHook(cx->runtime(), ShellModuleResolveHook);
|
||||||
|
JS::SetModuleDynamicImportHook(cx, ShellModuleDynamicImportHook);
|
||||||
JS::SetModuleMetadataHook(cx, ShellModuleMetadataHook);
|
JS::SetModuleMetadataHook(cx, ShellModuleMetadataHook);
|
||||||
|
|
||||||
result = Shell(cx, &op, envp);
|
result = Shell(cx, &op, envp);
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,7 @@
|
||||||
macro(GeneratorFunction, GeneratorFunction, "GeneratorFunction") \
|
macro(GeneratorFunction, GeneratorFunction, "GeneratorFunction") \
|
||||||
macro(get, get, "get") \
|
macro(get, get, "get") \
|
||||||
macro(getInternals, getInternals, "getInternals") \
|
macro(getInternals, getInternals, "getInternals") \
|
||||||
|
macro(GetModuleNamespace, GetModuleNamespace, "GetModuleNamespace") \
|
||||||
macro(getOwnPropertyDescriptor, getOwnPropertyDescriptor, "getOwnPropertyDescriptor") \
|
macro(getOwnPropertyDescriptor, getOwnPropertyDescriptor, "getOwnPropertyDescriptor") \
|
||||||
macro(getOwnPropertyNames, getOwnPropertyNames, "getOwnPropertyNames") \
|
macro(getOwnPropertyNames, getOwnPropertyNames, "getOwnPropertyNames") \
|
||||||
macro(getPrefix, getPrefix, "get ") \
|
macro(getPrefix, getPrefix, "get ") \
|
||||||
|
|
|
||||||
|
|
@ -3083,6 +3083,23 @@ js::GetModuleObjectForScript(JSScript* script)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value
|
||||||
|
js::FindScriptOrModulePrivateForScript(JSScript* script)
|
||||||
|
{
|
||||||
|
while (script) {
|
||||||
|
ScriptSourceObject* sso = &script->scriptSourceUnwrap();
|
||||||
|
Value value = sso->getPrivate();
|
||||||
|
if (!value.isUndefined()) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(sso->introductionScript() != script);
|
||||||
|
script = sso->introductionScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
return UndefinedValue();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc,
|
js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc,
|
||||||
MutableHandleValue res)
|
MutableHandleValue res)
|
||||||
|
|
|
||||||
|
|
@ -1075,7 +1075,11 @@ CreateObjectsForEnvironmentChain(JSContext* cx, AutoObjectVector& chain,
|
||||||
HandleObject terminatingEnv,
|
HandleObject terminatingEnv,
|
||||||
MutableHandleObject envObj);
|
MutableHandleObject envObj);
|
||||||
|
|
||||||
ModuleObject* GetModuleObjectForScript(JSScript* script);
|
ModuleObject*
|
||||||
|
GetModuleObjectForScript(JSScript* script);
|
||||||
|
|
||||||
|
Value
|
||||||
|
FindScriptOrModulePrivateForScript(JSScript* script);
|
||||||
|
|
||||||
ModuleEnvironmentObject* GetModuleEnvironmentForScript(JSScript* script);
|
ModuleEnvironmentObject* GetModuleEnvironmentForScript(JSScript* script);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4201,6 +4201,22 @@ CASE(JSOP_IMPORTMETA)
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_IMPORTMETA)
|
END_CASE(JSOP_IMPORTMETA)
|
||||||
|
|
||||||
|
CASE(JSOP_DYNAMIC_IMPORT)
|
||||||
|
{
|
||||||
|
ReservedRooted<Value> referencingPrivate(&rootValue0);
|
||||||
|
referencingPrivate = FindScriptOrModulePrivateForScript(script);
|
||||||
|
|
||||||
|
ReservedRooted<Value> specifier(&rootValue1);
|
||||||
|
POP_COPY_TO(specifier);
|
||||||
|
|
||||||
|
JSObject* promise = StartDynamicModuleImport(cx, referencingPrivate, specifier);
|
||||||
|
if (!promise)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
PUSH_OBJECT(*promise);
|
||||||
|
}
|
||||||
|
END_CASE(JSOP_DYNAMIC_IMPORT)
|
||||||
|
|
||||||
CASE(JSOP_SUPERFUN)
|
CASE(JSOP_SUPERFUN)
|
||||||
{
|
{
|
||||||
ReservedRooted<JSObject*> superEnvFunc(&rootObject0, &GetSuperEnvFunction(cx, REGS));
|
ReservedRooted<JSObject*> superEnvFunc(&rootObject0, &GetSuperEnvFunction(cx, REGS));
|
||||||
|
|
|
||||||
|
|
@ -2345,13 +2345,23 @@
|
||||||
* Operands:
|
* Operands:
|
||||||
* Stack: => import.meta
|
* Stack: => import.meta
|
||||||
*/ \
|
*/ \
|
||||||
macro(JSOP_IMPORTMETA, 233, "importmeta", NULL, 1, 0, 1, JOF_BYTE)
|
macro(JSOP_IMPORTMETA, 233, "importmeta", NULL, 1, 0, 1, JOF_BYTE) \
|
||||||
|
/*
|
||||||
|
* Dynamic import of the module specified by the string value on the top of
|
||||||
|
* the stack.
|
||||||
|
*
|
||||||
|
* Category: Variables and Scopes
|
||||||
|
* Type: Modules
|
||||||
|
* Operands:
|
||||||
|
* Stack: arg => rval
|
||||||
|
*/ \
|
||||||
|
macro(JSOP_DYNAMIC_IMPORT, 234, "call-import", NULL, 1, 1, 1, JOF_BYTE)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In certain circumstances it may be useful to "pad out" the opcode space to
|
* In certain circumstances it may be useful to "pad out" the opcode space to
|
||||||
* a power of two. Use this macro to do so.
|
* a power of two. Use this macro to do so.
|
||||||
*/
|
*/
|
||||||
#define FOR_EACH_TRAILING_UNUSED_OPCODE(macro) \
|
#define FOR_EACH_TRAILING_UNUSED_OPCODE(macro) \
|
||||||
macro(234) \
|
|
||||||
macro(235) \
|
macro(235) \
|
||||||
macro(236) \
|
macro(236) \
|
||||||
macro(237) \
|
macro(237) \
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,8 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||||
js::StackFormat::Default :
|
js::StackFormat::Default :
|
||||||
js::StackFormat::SpiderMonkey),
|
js::StackFormat::SpiderMonkey),
|
||||||
moduleResolveHook(),
|
moduleResolveHook(),
|
||||||
moduleMetadataHook()
|
moduleMetadataHook(),
|
||||||
|
moduleDynamicImportHook()
|
||||||
{
|
{
|
||||||
setGCStoreBufferPtr(&gc.storeBuffer);
|
setGCStoreBufferPtr(&gc.storeBuffer);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1300,6 +1300,10 @@ struct JSRuntime : public JS::shadow::Runtime,
|
||||||
// A hook that implements the abstract operations
|
// A hook that implements the abstract operations
|
||||||
// HostGetImportMetaProperties and HostFinalizeImportMeta.
|
// HostGetImportMetaProperties and HostFinalizeImportMeta.
|
||||||
JS::ModuleMetadataHook moduleMetadataHook;
|
JS::ModuleMetadataHook moduleMetadataHook;
|
||||||
|
|
||||||
|
// A hook that implements the abstract operation
|
||||||
|
// HostImportModuleDynamically.
|
||||||
|
JS::ModuleDynamicImportHook moduleDynamicImportHook;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
|
||||||
|
|
@ -1999,15 +1999,9 @@ intrinsic_HostResolveImportedModule(JSContext* cx, unsigned argc, Value* vp)
|
||||||
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
|
RootedModuleObject module(cx, &args[0].toObject().as<ModuleObject>());
|
||||||
RootedString specifier(cx, args[1].toString());
|
RootedString specifier(cx, args[1].toString());
|
||||||
|
|
||||||
JS::ModuleResolveHook moduleResolveHook = cx->runtime()->moduleResolveHook;
|
|
||||||
if (!moduleResolveHook) {
|
|
||||||
JS_ReportErrorASCII(cx, "Module resolve hook not set");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RootedObject result(cx);
|
|
||||||
RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
|
RootedValue referencingPrivate(cx, JS::GetModulePrivate(module));
|
||||||
result = moduleResolveHook(cx, referencingPrivate, specifier);
|
RootedObject result(cx, CallModuleResolveHook(cx, referencingPrivate, specifier));
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ AssertScopeMatchesEnvironment(Scope* scope, JSObject* originalEnv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScopeKind::Module:
|
case ScopeKind::Module:
|
||||||
MOZ_ASSERT(env->as<ModuleEnvironmentObject>().module().script() ==
|
MOZ_ASSERT(&env->as<ModuleEnvironmentObject>().module() ==
|
||||||
si.scope()->as<ModuleScope>().script());
|
si.scope()->as<ModuleScope>().module());
|
||||||
env = &env->as<ModuleEnvironmentObject>().enclosingEnvironment();
|
env = &env->as<ModuleEnvironmentObject>().enclosingEnvironment();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue