Skip to content

Commit 440508a

Browse files
committed
continue work
1 parent 69958f7 commit 440508a

File tree

11 files changed

+419
-175
lines changed

11 files changed

+419
-175
lines changed

compile_flags.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
-isystembazel-bin/src/rust/net/_virtual_includes/net@cxx
6464
-isystembazel-bin/src/rust/transpiler/_virtual_includes/transpiler@cxx
6565
-isystembazel-bin/src/rust/api/_virtual_includes/lib.rs@cxx
66+
-isystembazel-bin/src/rust/jsg/_virtual_includes/lib.rs@cxx
6667
-isystembazel-bin/src/rust/jsg/_virtual_includes/modules.rs@cxx
6768
-D_FORTIFY_SOURCE=1
6869
-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES

src/node/internal/internal_dns_client.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@ import * as errorCodes from 'node-internal:internal_dns_constants';
33
import { DnsError } from 'node-internal:internal_errors';
44
import { validateString } from 'node-internal:validators';
55

6+
import * as dnsKeys from 'node-internal:dns';
7+
8+
console.log({
9+
dnsUtil,
10+
dnsKeys,
11+
method: Object.keys(dnsUtil),
12+
parseCaaRecord: typeof dnsUtil.parseCaaRecord,
13+
hasParseCaaRecord: 'parseCaaRecord' in dnsUtil,
14+
});
15+
616
export type TTLResponse = {
717
ttl: number;
818
address: string;

src/rust/api/dns.rs

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -231,32 +231,37 @@ impl DnsUtil {
231231

232232
// Generated code.
233233
impl DnsUtil {
234-
fn parse_caa_record_callback(
235-
lock: *mut jsg::ffi::Lock,
236-
args: *mut jsg::ffi::Args,
237-
) -> jsg::Result<jsg::ffi::Value, jsg::Error> {
238-
let lock = unsafe { &mut *lock };
239-
let args = unsafe { &mut *args };
240-
let arg0 = args.get_arg(0);
241-
let arg0 = jsg::ffi::string_from_value(lock, arg0);
242-
match Self::parse_caa_record(arg0) {
243-
Ok(record) => Ok(jsg::ffi::value_from_jsg_struct(lock, &record)),
244-
Err(err) => Err(err.into()),
245-
}
234+
extern "C" fn parse_caa_record_callback(args: *mut jsg::v8::ffi::FunctionCallbackInfo) {
235+
// TODO: Get self from v8
236+
let isolate = unsafe { jsg::v8::ffi::get_isolate(args) };
237+
let this = unsafe { jsg::v8::ffi::get_this(args) };
238+
let len = unsafe { jsg::v8::ffi::get_length(args) };
239+
let arg0 = unsafe { jsg::v8::ffi::get_arg(args, 0) };
240+
241+
let arg0 = unsafe { jsg::v8::ffi::unwrap_string(isolate, arg0) };
242+
dbg!(arg0);
243+
244+
// let lock = unsafe { &mut *lock };
245+
// let args = unsafe { &mut *args };
246+
// let arg0 = args.get_arg(0);
247+
// let arg0 = jsg::v8::string_from_value(lock, arg0);
248+
// match Self::parse_caa_record(arg0) {
249+
// Ok(record) => Ok(jsg::v8::value_from_jsg_struct(lock, &record)),
250+
// Err(err) => Err(err.into()),
251+
// }
252+
todo!();
246253
}
247254

248-
fn parse_naptr_record_callback(
249-
lock: *mut jsg::ffi::Lock,
250-
args: *mut jsg::ffi::Args,
251-
) -> jsg::Result<jsg::ffi::Value, jsg::Error> {
252-
let lock = unsafe { &mut *lock };
253-
let args = unsafe { &mut *args };
254-
let arg0 = args.get_arg(0);
255-
let arg0 = jsg::ffi::string_from_value(lock, arg0);
256-
match Self::parse_naptr_record(arg0) {
257-
Ok(record) => Ok(jsg::ffi::value_from_jsg_struct(lock, &record)),
258-
Err(err) => Err(err.into()),
259-
}
255+
extern "C" fn parse_naptr_record_callback(args: *mut jsg::v8::ffi::FunctionCallbackInfo) {
256+
// let lock = unsafe { &mut *lock };
257+
// let args = unsafe { &mut *args };
258+
// let arg0 = args.get_arg(0);
259+
// let arg0 = jsg::v8::string_from_value(lock, arg0);
260+
// match Self::parse_naptr_record(arg0) {
261+
// Ok(record) => Ok(jsg::v8::value_from_jsg_struct(lock, &record)),
262+
// Err(err) => Err(err.into()),
263+
// }
264+
todo!();
260265
}
261266
}
262267

@@ -267,16 +272,20 @@ impl jsg::Resource for DnsUtil {
267272
Self: Sized,
268273
{
269274
vec![
270-
jsg::Member::StaticMethod {
275+
jsg::Member::Method {
271276
name: "parseCaaRecord",
272-
callback: Box::new(Self::parse_caa_record_callback),
277+
callback: Self::parse_caa_record_callback,
273278
},
274-
jsg::Member::StaticMethod {
279+
jsg::Member::Method {
275280
name: "parseNaptrRecord",
276-
callback: Box::new(Self::parse_naptr_record_callback),
281+
callback: Self::parse_naptr_record_callback,
277282
},
278283
]
279284
}
285+
286+
fn class_name() -> &'static str {
287+
"DnsUtil"
288+
}
280289
}
281290

282291
impl jsg::Type for DnsUtil {}

src/rust/api/lib.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,32 @@ pub mod dns;
77

88
#[cxx::bridge(namespace = "workerd::rust::api")]
99
mod ffi {
10+
#[namespace = "v8"]
11+
unsafe extern "C++" {
12+
include!("v8.h");
13+
type Isolate;
14+
}
15+
1016
#[namespace = "workerd::rust::jsg"]
1117
unsafe extern "C++" {
1218
include!("workerd/rust/jsg/ffi.h");
19+
1320
type ModuleRegistry = jsg::modules::ffi::ModuleRegistry;
14-
type LocalValue = jsg::v8::ffi::LocalValue;
15-
type ModuleCallback = jsg::modules::ffi::ModuleCallback;
21+
22+
fn register_add_builtin_module(
23+
registry: Pin<&mut ModuleRegistry>,
24+
specifier: &str,
25+
callback: unsafe fn(*mut Isolate) -> u64,
26+
);
1627
}
1728
extern "Rust" {
1829
pub fn register_nodejs_modules(registry: Pin<&mut ModuleRegistry>);
1930
}
2031
}
2132

2233
pub fn register_nodejs_modules(registry: Pin<&mut ffi::ModuleRegistry>) {
23-
todo!("register_nodejs_modules")
34+
ffi::register_add_builtin_module(registry, "node-internal:dns", |isolate| unsafe {
35+
let isolate_ptr = isolate as *mut jsg::ffi::Isolate;
36+
jsg::instantiate_resource::<dns::DnsUtil>(isolate_ptr).into_raw()
37+
});
2438
}

src/rust/jsg/BUILD.bazel

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,38 @@
1+
load("//:build/wd_cc_library.bzl", "wd_cc_library")
12
load("//:build/wd_rust_crate.bzl", "wd_rust_crate")
23

34
wd_rust_crate(
45
name = "jsg",
56
cxx_bridge_deps = ["//src/workerd/jsg"],
6-
cxx_bridge_srcs = ["modules.rs"],
7+
cxx_bridge_srcs = [
8+
"lib.rs",
9+
"modules.rs",
10+
"v8.rs",
11+
],
712
visibility = ["//visibility:public"],
13+
deps = [":ffi"],
14+
)
15+
16+
wd_cc_library(
17+
name = "bridge",
18+
srcs = [],
19+
hdrs = ["jsg.h"],
20+
visibility = ["//visibility:public"],
21+
deps = [":jsg"],
22+
)
23+
24+
wd_cc_library(
25+
name = "ffi",
26+
srcs = ["ffi.c++"],
27+
hdrs = ["ffi.h"],
28+
implementation_deps = [
29+
":lib.rs@cxx",
30+
":v8.rs@cxx",
31+
],
32+
visibility = ["//visibility:public"],
33+
deps = [
34+
"//src/workerd/jsg",
35+
"@workerd-cxx//kj-rs",
36+
"@workerd-v8//:v8",
37+
],
838
)

src/rust/jsg/ffi.c++

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include "ffi.h"
2+
3+
#include <workerd/jsg/util.h>
4+
#include <workerd/jsg/wrappable.h>
5+
#include <workerd/rust/jsg/lib.rs.h>
6+
7+
#include <kj/common.h>
8+
9+
using namespace kj_rs;
10+
11+
namespace workerd::rust::jsg {
12+
13+
v8::Local<v8::FunctionTemplate> get_template(
14+
v8::Isolate* isolate, const ResourceDescriptor& descriptor) {
15+
// Construct lazily.
16+
// v8::EscapableHandleScope scope(isolate);
17+
18+
v8::Local<v8::FunctionTemplate> constructor;
19+
KJ_IF_SOME(c, descriptor.constructor) {
20+
KJ_UNIMPLEMENTED("constructors are not implemented yet");
21+
// constructor =
22+
// v8::FunctionTemplate::New(isolate, &ConstructorCallback<TypeWrapper, T>::callback);
23+
} else {
24+
constructor = v8::FunctionTemplate::New(isolate, &workerd::jsg::throwIllegalConstructor);
25+
}
26+
27+
auto prototype = constructor->PrototypeTemplate();
28+
29+
// Signatures protect our methods from being invoked with the wrong `this`.
30+
// auto signature = v8::Signature::New(isolate, constructor);
31+
32+
auto instance = constructor->InstanceTemplate();
33+
34+
instance->SetInternalFieldCount(workerd::jsg::Wrappable::INTERNAL_FIELD_COUNT);
35+
36+
auto classname = ::workerd::jsg::v8StrIntern(isolate, kj::str(descriptor.name));
37+
38+
if (workerd::jsg::getShouldSetToStringTag(isolate)) {
39+
prototype->Set(v8::Symbol::GetToStringTag(isolate), classname, v8::PropertyAttribute::DontEnum);
40+
}
41+
42+
// Previously, miniflare would use the lack of a Symbol.toStringTag on a class to
43+
// detect a type that came from the runtime. That's obviously a bit problematic because
44+
// Symbol.toStringTag is required for full compliance on standard web platform APIs.
45+
// To help use cases where it is necessary to detect if a class is a runtime class, we
46+
// will add a special symbol to the prototype of the class to indicate. Note that
47+
// because this uses the global symbol registry user code could still mark their own
48+
// classes with this symbol but that's unlikely to be a problem in any practical case.
49+
auto internalMarker =
50+
v8::Symbol::For(isolate, ::workerd::jsg::v8StrIntern(isolate, "cloudflare:internal-class"));
51+
prototype->Set(internalMarker, internalMarker,
52+
static_cast<v8::PropertyAttribute>(v8::PropertyAttribute::DontEnum |
53+
v8::PropertyAttribute::DontDelete | v8::PropertyAttribute::ReadOnly));
54+
55+
constructor->SetClassName(classname);
56+
57+
// auto& typeWrapper = static_cast<TypeWrapper&>(*this);
58+
59+
// ResourceTypeBuilder<TypeWrapper, T, isContext> builder(
60+
// typeWrapper, isolate, constructor, instance, prototype, signature);
61+
62+
// if constexpr (isDetected<GetConfiguration, T>()) {
63+
// T::template registerMembers<decltype(builder), T>(builder, configuration);
64+
// } else {
65+
// T::template registerMembers<decltype(builder), T>(builder);
66+
// }
67+
68+
for (const auto& method: descriptor.static_methods) {
69+
auto functionTemplate = v8::FunctionTemplate::New(isolate,
70+
reinterpret_cast<v8::FunctionCallback>(reinterpret_cast<void*>(method.callback)),
71+
v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 0, v8::ConstructorBehavior::kThrow);
72+
functionTemplate->RemovePrototype();
73+
constructor->Set(::workerd::jsg::v8StrIntern(isolate, kj::str(method.name)), functionTemplate);
74+
}
75+
76+
for (const auto& method: descriptor.methods) {
77+
auto functionTemplate = v8::FunctionTemplate::New(isolate,
78+
reinterpret_cast<v8::FunctionCallback>(reinterpret_cast<void*>(method.callback)),
79+
v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 0, v8::ConstructorBehavior::kThrow);
80+
prototype->Set(::workerd::jsg::v8StrIntern(isolate, kj::str(method.name)), functionTemplate);
81+
}
82+
83+
// auto result = scope.Escape(constructor);
84+
// slot.Reset(isolate, result);
85+
return constructor;
86+
}
87+
88+
LocalValue instantiate_resource(v8::Isolate* isolate, const ResourceDescriptor& descriptor) {
89+
auto tmpl = get_template(isolate, descriptor);
90+
v8::Local<v8::Object> object =
91+
workerd::jsg::check(tmpl->InstanceTemplate()->NewInstance(isolate->GetCurrentContext()));
92+
return to_repr(object);
93+
}
94+
95+
} // namespace workerd::rust::jsg

0 commit comments

Comments
 (0)