0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-01-11 08:34:01 -05:00

feat: add various FunctionTemplate methods (#718)

This commit adds the following methods:
* `FunctionTemplate::inherit()`
* `FunctionTemplate::prototype_template()`
* `FunctionTemplate::read_only_prototype()`
* `FunctionTemplate::remove_prototype()`
This commit is contained in:
Jomer 2021-06-30 16:55:14 +02:00 committed by GitHub
parent f5add72f09
commit 89c8ae8af3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 131 additions and 0 deletions

View file

@ -1582,6 +1582,26 @@ void v8__FunctionTemplate__SetClassName(const v8::FunctionTemplate& self,
ptr_to_local(&self)->SetClassName(ptr_to_local(&name));
}
void v8__FunctionTemplate__Inherit(const v8::FunctionTemplate& self,
const v8::FunctionTemplate& parent) {
ptr_to_local(&self)->Inherit(ptr_to_local(&parent));
}
void v8__FunctionTemplate__ReadOnlyPrototype(const v8::FunctionTemplate& self) {
ptr_to_local(&self)->ReadOnlyPrototype();
}
void v8__FunctionTemplate__RemovePrototype(const v8::FunctionTemplate& self) {
ptr_to_local(&self)->RemovePrototype();
}
const v8::ObjectTemplate* v8__FunctionTemplate__PrototypeTemplate(
const v8::FunctionTemplate& self) {
return local_to_ptr(
ptr_to_local(&self)->PrototypeTemplate());
}
v8::Isolate* v8__FunctionCallbackInfo__GetIsolate(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return self.GetIsolate();

View file

@ -51,10 +51,19 @@ extern "C" {
this: *const FunctionTemplate,
context: *const Context,
) -> *const Function;
fn v8__FunctionTemplate__PrototypeTemplate(
this: *const FunctionTemplate,
) -> *const ObjectTemplate;
fn v8__FunctionTemplate__SetClassName(
this: *const FunctionTemplate,
name: *const String,
);
fn v8__FunctionTemplate__Inherit(
this: *const FunctionTemplate,
parent: *const FunctionTemplate,
);
fn v8__FunctionTemplate__ReadOnlyPrototype(this: *const FunctionTemplate);
fn v8__FunctionTemplate__RemovePrototype(this: *const FunctionTemplate);
fn v8__ObjectTemplate__New(
isolate: *mut Isolate,
@ -184,6 +193,35 @@ impl FunctionTemplate {
pub fn set_class_name(&self, name: Local<String>) {
unsafe { v8__FunctionTemplate__SetClassName(self, &*name) };
}
/// Returns the ObjectTemplate that is used by this
/// FunctionTemplate as a PrototypeTemplate
pub fn prototype_template<'s>(
&self,
scope: &mut HandleScope<'s, ()>,
) -> Local<'s, ObjectTemplate> {
unsafe {
scope.cast_local(|_sd| v8__FunctionTemplate__PrototypeTemplate(self))
}
.unwrap()
}
/// Causes the function template to inherit from a parent function template.
/// This means the function's prototype.__proto__ is set to the parent function's prototype.
pub fn inherit(&self, parent: Local<FunctionTemplate>) {
unsafe { v8__FunctionTemplate__Inherit(self, &*parent) };
}
/// Sets the ReadOnly flag in the attributes of the 'prototype' property
/// of functions created from this FunctionTemplate to true.
pub fn read_only_prototype(&self) {
unsafe { v8__FunctionTemplate__ReadOnlyPrototype(self) };
}
/// Removes the prototype property from functions created from this FunctionTemplate.
pub fn remove_prototype(&self) {
unsafe { v8__FunctionTemplate__RemovePrototype(self) };
}
}
impl ObjectTemplate {

View file

@ -1330,6 +1330,79 @@ fn function_template_signature() {
}
}
#[test]
fn function_template_prototype() {
let _setup_guard = setup();
let isolate = &mut v8::Isolate::new(Default::default());
{
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let scope = &mut v8::TryCatch::new(scope);
let function_templ = v8::FunctionTemplate::new(scope, fortytwo_callback);
let prototype_templ = function_templ.prototype_template(scope);
let amount_name = v8::String::new(scope, "amount").unwrap();
let value = v8::Number::new(scope, 1.0);
let second_value = v8::Number::new(scope, 2.0);
let third_value = v8::Number::new(scope, 3.0);
prototype_templ.set(amount_name.into(), value.into());
let function = function_templ.get_function(scope).unwrap();
function.new_instance(scope, &[]);
let object1 = function.new_instance(scope, &[]).unwrap();
assert!(!object1.is_null_or_undefined());
let name = v8::String::new(scope, "ob1").unwrap();
context
.global(scope)
.set(scope, name.into(), object1.into());
let actual_amount =
eval(scope, "ob1.amount").unwrap().to_number(scope).unwrap();
dbg!("{}", actual_amount.number_value(scope).unwrap());
assert!(value.eq(&actual_amount));
let object2 = function.new_instance(scope, &[]).unwrap();
assert!(!object2.is_null_or_undefined());
let name = v8::String::new(scope, "ob2").unwrap();
context
.global(scope)
.set(scope, name.into(), object2.into());
let actual_amount =
eval(scope, "ob2.amount").unwrap().to_number(scope).unwrap();
dbg!("{}", actual_amount.number_value(scope).unwrap());
assert!(value.eq(&actual_amount));
eval(scope, "ob1.amount = 2").unwrap();
let actual_amount =
eval(scope, "ob1.amount").unwrap().to_number(scope).unwrap();
dbg!("{}", actual_amount.number_value(scope).unwrap());
assert!(second_value.eq(&actual_amount));
// We need to get the prototype of the object to change it, it is not the same object as the prototype template!
object2
.get_prototype(scope)
.unwrap()
.to_object(scope)
.unwrap()
.set(scope, amount_name.into(), third_value.into());
let actual_amount =
eval(scope, "ob1.amount").unwrap().to_number(scope).unwrap();
dbg!("{}", actual_amount.number_value(scope).unwrap());
assert!(second_value.eq(&actual_amount));
let actual_amount =
eval(scope, "ob2.amount").unwrap().to_number(scope).unwrap();
dbg!("{}", actual_amount.number_value(scope).unwrap());
assert!(third_value.eq(&actual_amount));
}
}
#[test]
fn object_template_set_accessor() {
let _setup_guard = setup();