deno_core
deno_core copied to clipboard
op2 object wraps
Object wrap for Cppgc-backed objects
#[op2] will generate the glue code declarations for impl blocks to create JS objects in Rust using the op2 infra.
deno_core::extension!(
// ...
objects = [MyObject],
)
Currently supported bindings:
- constructor
- methods
- static methods
Planned support:
- getters
- setters
Future:
- webidl validation
Example:
// dompoint.rs
pub struct DOMPoint {
x: f64,
y: f64,
z: f64,
w: f64,
}
impl GarbageCollected for DOMPoint {}
#[op2]
impl DOMPoint {
#[constructor]
#[cppgc]
fn new(
x: Option<f64>,
y: Option<f64>,
z: Option<f64>,
w: Option<f64>,
) -> DOMPoint {
DOMPoint {
x: x.unwrap_or(0.0),
y: y.unwrap_or(0.0),
z: z.unwrap_or(0.0),
w: w.unwrap_or(0.0),
}
}
#[static_method]
#[cppgc]
fn from_point(
scope: &mut v8::HandleScope,
other: v8::Local<v8::Object>,
) -> Result<DOMPoint, AnyError> {
fn get(
scope: &mut v8::HandleScope,
other: v8::Local<v8::Object>,
key: &str,
) -> Option<f64> {
let key = v8::String::new(scope, key).unwrap();
other
.get(scope, key.into())
.map(|x| x.to_number(scope).unwrap().value())
}
Ok(DOMPoint {
x: get(scope, other, "x").unwrap_or(0.0),
y: get(scope, other, "y").unwrap_or(0.0),
z: get(scope, other, "z").unwrap_or(0.0),
w: get(scope, other, "w").unwrap_or(0.0),
})
}
#[fast]
fn x(&self) -> f64 {
self.x
}
}
import { DOMPoint } from "ext:core/ops";
const p = new DOMPoint(200, 300);
p.x(); // 200.0
Codecov Report
Attention: Patch coverage is 94.11765% with 18 lines in your changes missing coverage. Please review.
Project coverage is 81.47%. Comparing base (
0c7f83e) to head (f6b3ca7). Report is 163 commits behind head on main.
| Files with missing lines | Patch % | Lines |
|---|---|---|
| testing/checkin/runner/ops.rs | 81.81% | 8 Missing :warning: |
| ops/op2/dispatch_fast.rs | 37.50% | 5 Missing :warning: |
| ops/op2/object_wrap.rs | 96.87% | 2 Missing :warning: |
| core/extensions.rs | 90.90% | 1 Missing :warning: |
| ops/op2/config.rs | 90.90% | 1 Missing :warning: |
| ops/op2/dispatch_slow.rs | 87.50% | 1 Missing :warning: |
Additional details and impacted files
@@ Coverage Diff @@
## main #805 +/- ##
==========================================
+ Coverage 81.43% 81.47% +0.04%
==========================================
Files 97 98 +1
Lines 23877 25257 +1380
==========================================
+ Hits 19445 20579 +1134
- Misses 4432 4678 +246
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
Have you done any performance benchmarks?
$ target/release/dcore bench.js
JS x(): 87ms
Rust x(): 285ms
JS create: 904ms
Rust create: 1706ms
Benchmark
const { DOMPoint } = Deno.core.ops;
function bench(name, fn, iterations = 1e7) {
var start = Date.now();
for (var i = 0; i < iterations; i++) {
fn();
}
var end = Date.now();
console.log(name + ': ' + (end - start) + 'ms');
}
class DOMPointJS {
#x;
#y;
#z;
#w;
constructor(x, y, z, w) {
this.#x = x || 0;
this.#y = y || 0;
this.#z = z || 0;
this.#w = w || 1;
}
x() {
return this.#x;
}
}
const p = new DOMPointJS(100, 200);
function getXJS() {
return p.x()
}
const p2 = new DOMPoint(100, 200);
function getXRust() {
return p2.x();
}
bench('JS x()', getXJS);
bench('Rust x()', getXRust);
function createPointJS() {
return new DOMPointJS(100, 200);
}
function createPointRust() {
return new DOMPoint(100, 200);
}
bench('JS create', createPointJS);
bench('Rust create', createPointRust);
So...not great atm, working on it. Object::wrap and Object::unwrap can take Isolate instead of HandleScopes so we can avoid creating and dropping scope in most cases - which is 30% of the overhead.
Update benchmarks:
JS x(): 84ms
Rust x(): 191ms
JS create: 953ms
Rust create: 1810ms