-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
op2 object wraps #805
base: main
Are you sure you want to change the base?
op2 object wraps #805
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #805 +/- ##
==========================================
+ Coverage 81.43% 81.57% +0.14%
==========================================
Files 97 99 +2
Lines 23877 25092 +1215
==========================================
+ Hits 19445 20470 +1025
- Misses 4432 4622 +190 ☔ View full report in Codecov by Sentry. |
// To initialize object wraps correctly, we store the function | ||
// template in OpState with `T`'s TypeId as the key when binding | ||
// because it'll be pretty annoying to propogate `T` generic everywhere. | ||
// | ||
// Here we try to retrive a function template for `T`, falling back to | ||
// the default cppgc template. | ||
let id = TypeId::of::<T>(); | ||
let obj = if let Some(templ) = | ||
opstate.try_borrow_untyped::<v8::Global<v8::FunctionTemplate>>(id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a good solution. @devsnek thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work! Let's get @nathanwhit or @devsnek to give it another pass. This infra is great and am looking forward to rewrites of some of Deno APIs to use native code.
CC @petamoriken this PR will make it possible to land denoland/deno#22054.
// ```rust | ||
// deno_core::extension!( | ||
// ..., | ||
// objects = [MyObject], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we bike-shed on the name? prototypes
?
// ``` | ||
// | ||
// ```js | ||
// import { MyObject } from "ext:core/ops"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels somewhat odd that we import it from ext:core/ops
, fine for the first pass though 👍
test(function testDomPoint() { | ||
const p1 = new DOMPoint(100, 100); | ||
const p2 = new DOMPoint(); | ||
const p3 = DOMPoint.from_point({ x: 200 }); | ||
const p4 = DOMPoint.from_point({ x: 0, y: 100, z: 99.9, w: 100 }); | ||
assertEquals(p1.x(), 100); | ||
assertEquals(p2.x(), 0); | ||
assertEquals(p3.x(), 200); | ||
assertEquals(p4.x(), 0); | ||
|
||
let caught; | ||
try { | ||
// @ts-expect-error bad arg test | ||
new DOMPoint("bad"); | ||
} catch (e) { | ||
caught = e; | ||
} | ||
assert(caught); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is incredible
self.name.len() as u32 | ||
#[static_method] | ||
#[cppgc] | ||
fn from_point( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we have a #[rename("fromPoint")]
attribute?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if well-known symbols could also be supported
let id = op_method_ctx.id; | ||
op_state | ||
.borrow_mut() | ||
.put_untyped(id, v8::Global::new(scope, tmpl)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do these need to be registered as snapshot data?
Have you done any performance benchmarks? |
Benchmarkconst { 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. |
#[fast] | ||
fn x(&self) -> f64 { | ||
self.x | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also define accessor properties?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not in this PR but planned. It's a bit more work because accessors have different function signatures than normal ops
Update benchmarks:
|
74349f1
to
f0725dd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Object wrap for Cppgc-backed objects
#[op2]
will generate the glue code declarations forimpl
blocks to create JS objects in Rust using the op2 infra.Currently supported bindings:
Planned support:
Future:
Example: