Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@nightly
with:
toolchain: nightly-2025-05-14
toolchain: nightly-2025-10-31
components: rustfmt, clippy, llvm-tools-preview, rustc-dev
- name: Cache on ${{ github.ref_name }}
uses: Swatinem/rust-cache@v2
Expand All @@ -52,7 +52,7 @@ jobs:
- name: Clippy
run: |
cargo +stable clippy --all-targets -- -D warnings
cargo +nightly-2025-05-14 clippy --all-targets --all-features -- -D warnings
cargo +nightly-2025-10-31 clippy --all-targets --all-features -- -D warnings
- name: Dylint tests
working-directory: nova_lint
run: cargo test
Expand Down
6 changes: 3 additions & 3 deletions nova_lint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ name = "gc_scope_is_only_passed_by_value"
path = "ui/gc_scope_is_only_passed_by_value.rs"

[dependencies]
clippy_utils = { git = "https://github.com/rust-lang/rust-clippy", rev = "0450db33a5d8587f7c1d4b6d233dac963605766b" }
dylint_linting = { version = "4.1.0", features = ["constituent"] }
clippy_utils = { git = "https://github.com/rust-lang/rust-clippy", rev = "c936595d17413c1f08e162e117e504fb4ed126e4" }
dylint_linting = { version = "5.0.0", features = ["constituent"] }

[dev-dependencies]
dylint_testing = "4.1.0"
dylint_testing = "5.0.0"
nova_vm = { path = "../nova_vm" }

[package.metadata.rust-analyzer]
Expand Down
2 changes: 1 addition & 1 deletion nova_lint/rust-toolchain.toml → nova_lint/rust-toolchain
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-05-14"
channel = "nightly-2025-10-31"
components = ["llvm-tools-preview", "rustc-dev"]
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,6 @@ pub(crate) fn set_integrity_level<'a, T: Level>(
// 3. Perform ? DefinePropertyOrThrow(O, k, desc).
define_property_or_throw(agent, o, k.get(agent), desc, gc.reborrow()).unbind()?;
}
i += 1;
}
}
// 6. Return true.
Expand Down
2 changes: 1 addition & 1 deletion nova_vm/src/ecmascript/builtins/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ impl<'a> Array<'a> {
create_array_from_list(agent, elements, gc)
}

pub(crate) fn get_index(self) -> usize {
pub(crate) const fn get_index(self) -> usize {
self.0.into_index()
}

Expand Down
20 changes: 0 additions & 20 deletions nova_vm/src/ecmascript/builtins/array/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,23 +56,3 @@ impl HeapMarkAndSweep for ArrayHeapDataMut<'_, 'static> {
object_index.sweep_values(compactions);
}
}

impl HeapMarkAndSweep for ArrayHeapData<'static> {
fn mark_values(&self, queues: &mut WorkQueues) {
let Self {
object_index,
elements,
} = self;
object_index.mark_values(queues);
elements.mark_values(queues);
}

fn sweep_values(&mut self, compactions: &CompactionLists) {
let Self {
object_index,
elements,
} = self;
object_index.sweep_values(compactions);
elements.sweep_values(compactions);
}
}
2 changes: 2 additions & 0 deletions nova_vm/src/ecmascript/builtins/data_view/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
heap::{CompactionLists, HeapMarkAndSweep, WorkQueues},
};

#[derive(Debug)]
pub struct DataViewRecord<'a> {
pub(crate) object_index: Option<OrdinaryObject<'a>>,
// TODO: Add a helper function for a u32::MAX value which signifies an a under-construction value:
Expand All @@ -41,6 +42,7 @@ impl Default for DataViewRecord<'_> {
}

#[cfg(feature = "shared-array-buffer")]
#[derive(Debug)]
pub struct SharedDataViewRecord<'a> {
pub(crate) object_index: Option<OrdinaryObject<'a>>,
// TODO: Add a helper function for a u32::MAX value which signifies an a under-construction value:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl<'a> ArrayIterator<'a> {
Self(BaseIndex::from_u32_index(0))
}

pub(crate) fn get_index(self) -> usize {
pub(crate) const fn get_index(self) -> usize {
self.0.into_index()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,14 +440,15 @@ pub fn add_entries_from_iterable_map_constructor<'a>(
/// > element array-like object whose first element is a value that will be used
/// > as a Map key and whose second element is the value to associate with that
/// > key.
pub(crate) fn add_entries_from_iterable<'a>(
pub(crate) fn add_entries_from_iterable<'a, T: Into<Object<'a>> + TryFrom<Object<'a>>>(
agent: &mut Agent,
target: Map,
target: T,
iterable: Value,
adder: Function,
mut gc: GcScope<'a, '_>,
) -> JsResult<'a, Map<'a>> {
) -> JsResult<'a, T> {
let nogc = gc.nogc();
let target: Object = target.into();
let target = target.scope(agent, nogc);
let iterable = iterable.bind(nogc);
let adder = adder.scope(agent, nogc);
Expand Down Expand Up @@ -482,7 +483,11 @@ pub(crate) fn add_entries_from_iterable<'a>(
.bind(gc.nogc());
// b. If next is DONE, return target.
let Some(next) = next else {
return Ok(target.get(agent).bind(gc.into_nogc()));
// SAFETY: not shared.
let target = unsafe { target.take(agent).bind(gc.into_nogc()) };
// SAFETY: passed in type is still the same type.
let target = unsafe { T::try_from(target).unwrap_unchecked() };
return Ok(target);
};
// c. If next is not an Object, then
let Ok(next) = Object::try_from(next) else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl MapIterator<'_> {
Self(BaseIndex::from_u32_index(0))
}

pub(crate) fn get_index(self) -> usize {
pub(crate) const fn get_index(self) -> usize {
self.0.into_index()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl SetIterator<'_> {
Self(BaseIndex::from_u32_index(0))
}

pub(crate) fn get_index(self) -> usize {
pub(crate) const fn get_index(self) -> usize {
self.0.into_index()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::hint::unreachable_unchecked;

use crate::{
ecmascript::{
abstract_operations::{operations_on_objects::get, testing_and_comparison::is_callable},
builders::builtin_function_builder::BuiltinFunctionBuilder,
builtins::{ArgumentsList, Behaviour, Builtin, BuiltinIntrinsicConstructor},
execution::{Agent, JsResult, Realm},
types::{BUILTIN_STRING_MEMORY, IntoObject, Object, String, Value},
builtins::{
ArgumentsList, Behaviour, Builtin, BuiltinIntrinsicConstructor,
keyed_collections::map_objects::map_constructor::add_entries_from_iterable,
ordinary::ordinary_create_from_constructor,
},
execution::{Agent, JsResult, ProtoIntrinsics, Realm, agent::ExceptionType},
types::{BUILTIN_STRING_MEMORY, Function, IntoObject, IntoValue, Object, String, Value},
},
engine::{
context::{Bindable, GcScope},
rootable::Scopable,
},
engine::context::GcScope,
heap::IntrinsicConstructorIndexes,
};

Expand All @@ -36,18 +46,74 @@ impl WeakMapConstructor {
fn constructor<'gc>(
agent: &mut Agent,
_this_value: Value,
_arguments: ArgumentsList,
_new_target: Option<Object>,
gc: GcScope<'gc, '_>,
arguments: ArgumentsList,
new_target: Option<Object>,
mut gc: GcScope<'gc, '_>,
) -> JsResult<'gc, Value<'gc>> {
let iterable = arguments.get(0).bind(gc.nogc());
// 1. If NewTarget is undefined, throw a TypeError exception.
let Some(new_target) = new_target else {
return Err(agent.throw_exception_with_static_message(
ExceptionType::TypeError,
"WeakMap Constructor requires 'new'",
gc.into_nogc(),
));
};
let Ok(new_target) = Function::try_from(new_target) else {
return Err(agent.throw_exception_with_static_message(
ExceptionType::TypeError,
"Function Proxies not yet supported",
gc.into_nogc(),
));
};
let iterable_is_undefined_or_null = iterable.is_undefined() || iterable.is_null();
let iterable = iterable.scope(agent, gc.nogc());
// 2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
let Object::WeakMap(map) = ordinary_create_from_constructor(
agent,
new_target,
ProtoIntrinsics::WeakMap,
gc.reborrow(),
)
.unbind()?
else {
// SAFETY: ProtoIntrinsics guarded.
unsafe { unreachable_unchecked() }
};
// 3. Set map.[[WeakMapData]] to a new empty List.
// 4. If iterable is either undefined or null, return map.
if iterable_is_undefined_or_null {
return Ok(map.into_value());
}
let scoped_map = map.scope(agent, gc.nogc());
// 5. Let adder be ? Get(map, "set").
let adder = get(
agent,
map.unbind(),
BUILTIN_STRING_MEMORY.set.to_property_key(),
gc.reborrow(),
)
.unbind()?
.bind(gc.nogc());
// 6. If IsCallable(adder) is false, throw a TypeError exception.
let Some(adder) = is_callable(adder, gc.nogc()) else {
return Err(agent.throw_exception_with_static_message(
ExceptionType::TypeError,
"expected 'add' to be a function",
gc.into_nogc(),
));
};
// 7. Return ? AddEntriesFromIterable(map, iterable, adder).
Err(agent.todo("WeakMap", gc.into_nogc()))
add_entries_from_iterable(
agent,
// SAFETY: not shared.
unsafe { scoped_map.take(agent) },
// SAFETY: not shared.
unsafe { iterable.take(agent) },
adder.unbind(),
gc,
)
.map(|m| m.into_value())
}

pub(crate) fn create_intrinsic(agent: &mut Agent, realm: Realm<'static>) {
Expand Down
Loading
Loading