Skip to content

Commit 6e6c160

Browse files
committed
new global modes
1 parent 2de66e1 commit 6e6c160

File tree

9 files changed

+89
-112
lines changed

9 files changed

+89
-112
lines changed

cli/module_loader.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use crate::util::text_encoding::code_without_source_map;
3535
use crate::util::text_encoding::source_map_from_code;
3636
use crate::worker::ModuleLoaderAndSourceMapGetter;
3737
use crate::worker::ModuleLoaderFactory;
38-
3938
use deno_ast::MediaType;
4039
use deno_core::anyhow::anyhow;
4140
use deno_core::anyhow::bail;
@@ -64,6 +63,7 @@ use deno_graph::Module;
6463
use deno_graph::ModuleGraph;
6564
use deno_graph::Resolution;
6665
use deno_runtime::code_cache;
66+
use deno_runtime::deno_node::get_host_defined_options;
6767
use deno_runtime::deno_permissions::PermissionsContainer;
6868
use deno_semver::npm::NpmPackageReqReference;
6969
use node_resolver::NodeResolutionMode;
@@ -724,6 +724,19 @@ impl<TGraphContainer: ModuleGraphContainer> ModuleLoader
724724
Ok(specifier)
725725
}
726726

727+
fn get_host_defined_options<'s>(
728+
&self,
729+
scope: &mut deno_core::v8::HandleScope<'s>,
730+
name: &str,
731+
) -> Option<deno_core::v8::Local<'s, deno_core::v8::Data>> {
732+
let name = deno_core::ModuleSpecifier::parse(name).ok()?;
733+
if self.0.shared.node_resolver.in_npm_package(&name) {
734+
Some(get_host_defined_options(scope))
735+
} else {
736+
None
737+
}
738+
}
739+
727740
fn load(
728741
&self,
729742
specifier: &ModuleSpecifier,

cli/standalone/mod.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use deno_core::ResolutionKind;
2525
use deno_npm::npm_rc::ResolvedNpmRc;
2626
use deno_package_json::PackageJsonDepValue;
2727
use deno_runtime::deno_fs;
28+
use deno_runtime::deno_node::get_host_defined_options;
2829
use deno_runtime::deno_node::NodeResolver;
2930
use deno_runtime::deno_permissions::Permissions;
3031
use deno_runtime::deno_permissions::PermissionsContainer;
@@ -267,6 +268,19 @@ impl ModuleLoader for EmbeddedModuleLoader {
267268
}
268269
}
269270

271+
fn get_host_defined_options<'s>(
272+
&self,
273+
scope: &mut deno_core::v8::HandleScope<'s>,
274+
name: &str,
275+
) -> Option<deno_core::v8::Local<'s, deno_core::v8::Data>> {
276+
let name = deno_core::ModuleSpecifier::parse(name).ok()?;
277+
if self.shared.node_resolver.in_npm_package(&name) {
278+
Some(get_host_defined_options(scope))
279+
} else {
280+
None
281+
}
282+
}
283+
270284
fn load(
271285
&self,
272286
original_specifier: &ModuleSpecifier,

ext/node/global.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
22

3-
use std::mem::MaybeUninit;
4-
53
use deno_core::v8;
64
use deno_core::v8::GetPropertyNamesArgs;
75
use deno_core::v8::MapFnTo;
86

9-
use crate::NodeResolverRc;
10-
117
// NOTE(bartlomieju): somehow calling `.map_fn_to()` multiple times on a function
128
// returns two different pointers. That shouldn't be the case as `.map_fn_to()`
139
// creates a thin wrapper that is a pure function. @piscisaureus suggests it
@@ -239,19 +235,19 @@ fn is_managed_key(
239235
}
240236

241237
fn current_mode(scope: &mut v8::HandleScope) -> Mode {
242-
let Some(v8_string) =
243-
v8::StackTrace::current_script_name_or_source_url(scope)
238+
let Some(host_defined_options) = scope.get_current_host_defined_options()
244239
else {
245240
return Mode::Deno;
246241
};
247-
let op_state = deno_core::JsRuntime::op_state_from(scope);
248-
let op_state = op_state.borrow();
249-
let Some(node_resolver) = op_state.try_borrow::<NodeResolverRc>() else {
250-
return Mode::Deno;
242+
// SAFETY: host defined options must always be a PrimitiveArray in current V8.
243+
let host_defined_options = unsafe {
244+
v8::Local::<v8::PrimitiveArray>::cast_unchecked(host_defined_options)
251245
};
252-
let mut buffer = [MaybeUninit::uninit(); 2048];
253-
let str = v8_string.to_rust_cow_lossy(scope, &mut buffer);
254-
if str.starts_with("node:") || node_resolver.in_npm_package_with_cache(str) {
246+
if host_defined_options.length() < 1 {
247+
return Mode::Deno;
248+
}
249+
let is_node = host_defined_options.get(scope, 0).is_true();
250+
if is_node {
255251
Mode::Node
256252
} else {
257253
Mode::Deno

ext/node/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,3 +836,12 @@ impl<'a> deno_package_json::fs::DenoPkgJsonFs for DenoPkgJsonFsAdapter<'a> {
836836
.map_err(|err| err.into_io_error())
837837
}
838838
}
839+
840+
pub fn get_host_defined_options<'s>(
841+
scope: &mut v8::HandleScope<'s>,
842+
) -> v8::Local<'s, v8::Data> {
843+
let host_defined_options = v8::PrimitiveArray::new(scope, 1);
844+
let value = v8::Boolean::new(scope, true);
845+
host_defined_options.set(scope, 0, value.into());
846+
host_defined_options.into()
847+
}

ext/node/ops/vm_internal.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
22

3+
use crate::get_host_defined_options;
34
use deno_core::error::type_error;
45
use deno_core::error::AnyError;
56
use deno_core::v8;
@@ -19,7 +20,22 @@ impl ContextifyScript {
1920
scope: &mut v8::HandleScope,
2021
source_str: v8::Local<v8::String>,
2122
) -> Result<Self, AnyError> {
22-
let source = v8::script_compiler::Source::new(source_str, None);
23+
let resource_name = v8::undefined(scope);
24+
let host_defined_options = get_host_defined_options(scope);
25+
let origin = v8::ScriptOrigin::new(
26+
scope,
27+
resource_name.into(),
28+
0,
29+
0,
30+
false,
31+
0,
32+
None,
33+
false,
34+
false,
35+
false,
36+
Some(host_defined_options),
37+
);
38+
let source = v8::script_compiler::Source::new(source_str, Some(&origin));
2339

2440
let unbound_script = v8::script_compiler::compile_unbound_script(
2541
scope,

ext/node/polyfills/01_require.js

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -976,9 +976,14 @@ function wrapSafe(
976976
filename,
977977
content,
978978
cjsModuleInstance,
979+
format,
979980
) {
980981
const wrapper = Module.wrap(content);
981-
const [f, err] = core.evalContext(wrapper, `file://${filename}`);
982+
const [f, err] = core.evalContext(
983+
wrapper,
984+
url.pathToFileURL(filename).toString(),
985+
[format !== "module"],
986+
);
982987
if (err) {
983988
if (process.mainModule === cjsModuleInstance) {
984989
enrichCJSError(err.thrown);
@@ -995,8 +1000,16 @@ function wrapSafe(
9951000
return f;
9961001
}
9971002

998-
Module.prototype._compile = function (content, filename) {
999-
const compiledWrapper = wrapSafe(filename, content, this);
1003+
Module.prototype._compile = function (content, filename, format) {
1004+
const compiledWrapper = wrapSafe(filename, content, this, format);
1005+
1006+
if (format === "module") {
1007+
// TODO: implement require esm
1008+
throw createRequireEsmError(
1009+
filename,
1010+
moduleParentCache.get(module)?.filename,
1011+
);
1012+
}
10001013

10011014
const dirname = pathDirname(filename);
10021015
const require = makeRequireFunction(this);
@@ -1053,17 +1066,24 @@ Module.prototype._compile = function (content, filename) {
10531066
Module._extensions[".js"] = function (module, filename) {
10541067
const content = op_require_read_file(filename);
10551068

1069+
let format;
10561070
if (StringPrototypeEndsWith(filename, ".js")) {
10571071
const pkg = op_require_read_closest_package_json(filename);
1058-
if (pkg && pkg.typ === "module") {
1072+
if (pkg?.typ === "module") {
1073+
// TODO: implement require esm
1074+
format = "module";
10591075
throw createRequireEsmError(
10601076
filename,
10611077
moduleParentCache.get(module)?.filename,
10621078
);
1079+
} else if (pkg?.type === "commonjs") {
1080+
format = "commonjs";
10631081
}
1082+
} else if (StringPrototypeEndsWith(filename, ".cjs")) {
1083+
format = "commonjs";
10641084
}
10651085

1066-
module._compile(content, filename);
1086+
module._compile(content, filename, format);
10671087
};
10681088

10691089
function createRequireEsmError(filename, parent) {

ext/node_resolver/resolution.rs

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
22

33
use std::borrow::Cow;
4-
use std::collections::HashMap;
54
use std::path::Path;
65
use std::path::PathBuf;
76

@@ -138,38 +137,17 @@ pub type NodeResolverRc<TEnv> = crate::sync::MaybeArc<NodeResolver<TEnv>>;
138137
pub struct NodeResolver<TEnv: NodeResolverEnv> {
139138
env: TEnv,
140139
npm_resolver: NpmResolverRc,
141-
in_npm_package_cache: crate::sync::MaybeArcMutex<HashMap<String, bool>>,
142140
}
143141

144142
impl<TEnv: NodeResolverEnv> NodeResolver<TEnv> {
145143
pub fn new(env: TEnv, npm_resolver: NpmResolverRc) -> Self {
146-
Self {
147-
env,
148-
npm_resolver,
149-
in_npm_package_cache: crate::sync::MaybeArcMutex::new(HashMap::new()),
150-
}
144+
Self { env, npm_resolver }
151145
}
152146

153147
pub fn in_npm_package(&self, specifier: &Url) -> bool {
154148
self.npm_resolver.in_npm_package(specifier)
155149
}
156150

157-
pub fn in_npm_package_with_cache(&self, specifier: Cow<str>) -> bool {
158-
let mut cache = self.in_npm_package_cache.lock();
159-
160-
if let Some(result) = cache.get(specifier.as_ref()) {
161-
return *result;
162-
}
163-
164-
let result = if let Ok(specifier) = Url::parse(&specifier) {
165-
self.npm_resolver.in_npm_package(&specifier)
166-
} else {
167-
false
168-
};
169-
cache.insert(specifier.into_owned(), result);
170-
result
171-
}
172-
173151
/// This function is an implementation of `defaultResolve` in
174152
/// `lib/internal/modules/esm/resolve.js` from Node.
175153
pub fn resolve(

ext/node_resolver/sync.rs

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,81 +6,13 @@ pub use inner::*;
66
mod inner {
77
#![allow(clippy::disallowed_types)]
88

9-
use std::ops::Deref;
10-
use std::ops::DerefMut;
119
pub use std::sync::Arc as MaybeArc;
1210

13-
pub struct MaybeArcMutexGuard<'lock, T>(std::sync::MutexGuard<'lock, T>);
14-
15-
impl<'lock, T> Deref for MaybeArcMutexGuard<'lock, T> {
16-
type Target = std::sync::MutexGuard<'lock, T>;
17-
fn deref(&self) -> &std::sync::MutexGuard<'lock, T> {
18-
&self.0
19-
}
20-
}
21-
22-
impl<'lock, T> DerefMut for MaybeArcMutexGuard<'lock, T> {
23-
fn deref_mut(&mut self) -> &mut std::sync::MutexGuard<'lock, T> {
24-
&mut self.0
25-
}
26-
}
27-
28-
#[derive(Debug)]
29-
pub struct MaybeArcMutex<T>(std::sync::Arc<std::sync::Mutex<T>>);
30-
impl<T> MaybeArcMutex<T> {
31-
pub fn new(val: T) -> Self {
32-
Self(std::sync::Arc::new(std::sync::Mutex::new(val)))
33-
}
34-
}
35-
36-
impl<'lock, T> MaybeArcMutex<T> {
37-
pub fn lock(&'lock self) -> MaybeArcMutexGuard<'lock, T> {
38-
MaybeArcMutexGuard(self.0.lock().unwrap())
39-
}
40-
}
41-
4211
pub use core::marker::Send as MaybeSend;
4312
pub use core::marker::Sync as MaybeSync;
4413
}
4514

4615
#[cfg(not(feature = "sync"))]
4716
mod inner {
48-
use std::ops::Deref;
49-
use std::ops::DerefMut;
50-
5117
pub use std::rc::Rc as MaybeArc;
52-
53-
pub struct MaybeArcMutexGuard<'lock, T>(std::cell::RefMut<'lock, T>);
54-
55-
impl<'lock, T> Deref for MaybeArcMutexGuard<'lock, T> {
56-
type Target = std::cell::RefMut<'lock, T>;
57-
fn deref(&self) -> &std::cell::RefMut<'lock, T> {
58-
&self.0
59-
}
60-
}
61-
62-
impl<'lock, T> DerefMut for MaybeArcMutexGuard<'lock, T> {
63-
fn deref_mut(&mut self) -> &mut std::cell::RefMut<'lock, T> {
64-
&mut self.0
65-
}
66-
}
67-
68-
#[derive(Debug)]
69-
pub struct MaybeArcMutex<T>(std::rc::Rc<std::cell::RefCell<T>>);
70-
impl<T> MaybeArcMutex<T> {
71-
pub fn new(val: T) -> Self {
72-
Self(std::rc::Rc::new(std::cell::RefCell::new(val)))
73-
}
74-
}
75-
76-
impl<'lock, T> MaybeArcMutex<T> {
77-
pub fn lock(&'lock self) -> MaybeArcMutexGuard<'lock, T> {
78-
MaybeArcMutexGuard(self.0.borrow_mut())
79-
}
80-
}
81-
82-
pub trait MaybeSync {}
83-
impl<T> MaybeSync for T where T: ?Sized {}
84-
pub trait MaybeSend {}
85-
impl<T> MaybeSend for T where T: ?Sized {}
8618
}

tests/node_compat/test/common/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ let knownGlobals = [
5959
queueMicrotask,
6060
removeEventListener,
6161
reportError,
62-
self,
6362
sessionStorage,
6463
setImmediate,
6564
];

0 commit comments

Comments
 (0)