1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
use std::unreachable;
use crate::{
module::ModuleKind,
vm::{opcode::Operation, ActiveRunnable, CompletionType},
Context, JsObject, JsResult, JsValue,
};
/// `NewTarget` implements the Opcode Operation for `Opcode::NewTarget`
///
/// Operation:
/// - Push the current new target to the stack.
#[derive(Debug, Clone, Copy)]
pub(crate) struct NewTarget;
impl Operation for NewTarget {
const NAME: &'static str = "NewTarget";
const INSTRUCTION: &'static str = "INST - NewTarget";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let new_target = if let Some(new_target) = context
.vm
.environments
.get_this_environment()
.as_function()
.and_then(|env| env.slots().new_target().cloned())
{
new_target.into()
} else {
JsValue::undefined()
};
context.vm.push(new_target);
Ok(CompletionType::Normal)
}
}
/// `ImportMeta` implements the Opcode Operation for `Opcode::ImportMeta`
///
/// Operation:
/// - Push the current `import.meta` to the stack
#[derive(Debug, Clone, Copy)]
pub(crate) struct ImportMeta;
impl Operation for ImportMeta {
const NAME: &'static str = "ImportMeta";
const INSTRUCTION: &'static str = "INST - ImportMeta";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
// Meta Properties
//
// ImportMeta : import . meta
//
// https://tc39.es/ecma262/#sec-meta-properties
// 1. Let module be GetActiveScriptOrModule().
let Some(ActiveRunnable::Module(module)) = context.vm.active_runnable.clone() else {
unreachable!("2. Assert: module is a Source Text Module Record.");
};
let ModuleKind::SourceText(src) = module.kind() else {
unreachable!("2. Assert: module is a Source Text Module Record.");
};
// 3. Let importMeta be module.[[ImportMeta]].
// 4. If importMeta is empty, then
// 5. Else,
// a. Assert: importMeta is an Object.
let import_meta = src
.import_meta()
.borrow_mut()
.get_or_insert_with(|| {
// a. Set importMeta to OrdinaryObjectCreate(null).
let import_meta = JsObject::with_null_proto();
// b. Let importMetaValues be HostGetImportMetaProperties(module).
// c. For each Record { [[Key]], [[Value]] } p of importMetaValues, do
// i. Perform ! CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]]).
// d. Perform HostFinalizeImportMeta(importMeta, module).
context
.module_loader()
.init_import_meta(&import_meta, &module, context);
// e. Set module.[[ImportMeta]] to importMeta.
import_meta
})
.clone();
// b. Return importMeta.
// f. Return importMeta.
context.vm.push(import_meta);
Ok(CompletionType::Normal)
}
}