mirror of https://github.com/boa-dev/boa.git
José Julián Espina
1 year ago
committed by
GitHub
13 changed files with 219 additions and 92 deletions
@ -0,0 +1,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) |
||||
} |
||||
} |
@ -1,32 +0,0 @@
|
||||
use crate::{ |
||||
vm::{opcode::Operation, CompletionType}, |
||||
Context, JsResult, JsValue, |
||||
}; |
||||
|
||||
/// `PushNewTarget` implements the Opcode Operation for `Opcode::PushNewTarget`
|
||||
///
|
||||
/// Operation:
|
||||
/// - Push the current new target to the stack.
|
||||
#[derive(Debug, Clone, Copy)] |
||||
pub(crate) struct PushNewTarget; |
||||
|
||||
impl Operation for PushNewTarget { |
||||
const NAME: &'static str = "PushNewTarget"; |
||||
const INSTRUCTION: &'static str = "INST - PushNewTarget"; |
||||
|
||||
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) |
||||
} |
||||
} |
Loading…
Reference in new issue