#![allow(non_snake_case, unused)]
use crate::quickjs::core::{current_ctx, intern_dup, jsval_of};
use crate::quickjs::quickjs_sys::*;
use crate::{PropertyDescriptor, Value};
struct PdImpl {
ctx: *mut JSContext,
has_enumerable: bool,
enumerable: bool,
has_configurable: bool,
configurable: bool,
has_writable: bool,
writable: bool,
value: JSValue,
has_value: bool,
get: JSValue,
has_get: bool,
set: JSValue,
has_set: bool,
}
impl PdImpl {
fn empty() -> Self {
PdImpl {
ctx: current_ctx(),
has_enumerable: false,
enumerable: false,
has_configurable: false,
configurable: false,
has_writable: false,
writable: false,
value: jsv_undefined(),
has_value: false,
get: jsv_undefined(),
has_get: false,
set: jsv_undefined(),
has_set: false,
}
}
}
#[inline]
unsafe fn imp<'a>(this: *const PropertyDescriptor) -> &'a PdImpl {
let p = *(this as *const usize) as *const PdImpl;
&*p
}
#[inline]
unsafe fn imp_mut<'a>(this: *mut PropertyDescriptor) -> &'a mut PdImpl {
let p = *(this as *const usize) as *mut PdImpl;
&mut *p
}
#[inline]
unsafe fn write_impl(out: *mut PropertyDescriptor, pd: PdImpl) {
let boxed = Box::into_raw(Box::new(pd));
*(out as *mut usize) = boxed as usize;
}
#[inline]
unsafe fn dup_handle(ctx: *mut JSContext, v: *const Value) -> JSValue {
let jv = jsval_of(v);
if ctx.is_null() {
return jv;
}
JS_DupValue(ctx, jv)
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__CONSTRUCT(
out: *mut PropertyDescriptor,
) {
unsafe {
write_impl(out, PdImpl::empty());
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__CONSTRUCT__Value(
this: *const PropertyDescriptor,
value: *const Value,
) {
unsafe {
let mut pd = PdImpl::empty();
pd.value = dup_handle(pd.ctx, value);
pd.has_value = true;
write_impl(this as *mut PropertyDescriptor, pd);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__CONSTRUCT__Value_Writable(
this: *const PropertyDescriptor,
value: *const Value,
writable: bool,
) {
unsafe {
let mut pd = PdImpl::empty();
pd.value = dup_handle(pd.ctx, value);
pd.has_value = true;
pd.writable = writable;
pd.has_writable = true;
write_impl(this as *mut PropertyDescriptor, pd);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__CONSTRUCT__Get_Set(
this: *const PropertyDescriptor,
get: *const Value,
set: *const Value,
) {
unsafe {
let mut pd = PdImpl::empty();
pd.get = dup_handle(pd.ctx, get);
pd.has_get = true;
pd.set = dup_handle(pd.ctx, set);
pd.has_set = true;
write_impl(this as *mut PropertyDescriptor, pd);
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__DESTRUCT(
this: *mut PropertyDescriptor,
) {
unsafe {
let slot = this as *mut usize;
let raw = *slot as *mut PdImpl;
if raw.is_null() {
return;
}
let pd = Box::from_raw(raw);
if !pd.ctx.is_null() {
if pd.has_value {
JS_FreeValue(pd.ctx, pd.value);
}
if pd.has_get {
JS_FreeValue(pd.ctx, pd.get);
}
if pd.has_set {
JS_FreeValue(pd.ctx, pd.set);
}
}
*slot = 0;
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__configurable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).configurable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__enumerable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).enumerable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__writable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).writable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__value(
this: *const PropertyDescriptor,
) -> *const Value {
unsafe {
let pd = imp(this);
if !pd.has_value {
return std::ptr::null();
}
intern_dup::<Value>(pd.ctx, pd.value)
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__get(
this: *const PropertyDescriptor,
) -> *const Value {
unsafe {
let pd = imp(this);
if !pd.has_get {
return std::ptr::null();
}
intern_dup::<Value>(pd.ctx, pd.get)
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__set(
this: *const PropertyDescriptor,
) -> *const Value {
unsafe {
let pd = imp(this);
if !pd.has_set {
return std::ptr::null();
}
intern_dup::<Value>(pd.ctx, pd.set)
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_configurable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_configurable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_enumerable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_enumerable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_writable(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_writable }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_value(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_value }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_get(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_get }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__has_set(
this: *const PropertyDescriptor,
) -> bool {
unsafe { imp(this).has_set }
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__set_enumerable(
this: *mut PropertyDescriptor,
enumerable: bool,
) {
unsafe {
let pd = imp_mut(this);
pd.enumerable = enumerable;
pd.has_enumerable = true;
}
}
#[unsafe(no_mangle)]
pub extern "C" fn v8__PropertyDescriptor__set_configurable(
this: *mut PropertyDescriptor,
configurable: bool,
) {
unsafe {
let pd = imp_mut(this);
pd.configurable = configurable;
pd.has_configurable = true;
}
}
use std::os::raw::c_int;
unsafe extern "C" {
fn JS_DefineProperty(
ctx: *mut JSContext,
this_obj: JSValue,
prop: JSAtom,
val: JSValue,
getter: JSValue,
setter: JSValue,
flags: c_int,
) -> c_int;
}
const JS_PROP_CONFIGURABLE: c_int = 1 << 0;
const JS_PROP_WRITABLE: c_int = 1 << 1;
const JS_PROP_ENUMERABLE: c_int = 1 << 2;
const JS_PROP_HAS_CONFIGURABLE: c_int = 1 << 8;
const JS_PROP_HAS_WRITABLE: c_int = 1 << 9;
const JS_PROP_HAS_ENUMERABLE: c_int = 1 << 10;
const JS_PROP_HAS_GET: c_int = 1 << 11;
const JS_PROP_HAS_SET: c_int = 1 << 12;
const JS_PROP_HAS_VALUE: c_int = 1 << 13;
const JS_PROP_THROW: c_int = 1 << 14;
pub(crate) fn pd_define(
ctx: *mut JSContext,
obj: JSValue,
atom: JSAtom,
this: *const PropertyDescriptor,
) -> c_int {
let pd = unsafe { imp(this) };
let mut flags: c_int = JS_PROP_THROW;
let mut val = jsv_undefined();
let mut getter = jsv_undefined();
let mut setter = jsv_undefined();
if pd.has_value {
flags |= JS_PROP_HAS_VALUE;
val = pd.value;
}
if pd.has_get {
flags |= JS_PROP_HAS_GET;
getter = pd.get;
}
if pd.has_set {
flags |= JS_PROP_HAS_SET;
setter = pd.set;
}
if pd.has_writable {
flags |= JS_PROP_HAS_WRITABLE;
if pd.writable {
flags |= JS_PROP_WRITABLE;
}
}
if pd.has_enumerable {
flags |= JS_PROP_HAS_ENUMERABLE;
if pd.enumerable {
flags |= JS_PROP_ENUMERABLE;
}
}
if pd.has_configurable {
flags |= JS_PROP_HAS_CONFIGURABLE;
if pd.configurable {
flags |= JS_PROP_CONFIGURABLE;
}
}
unsafe { JS_DefineProperty(ctx, obj, atom, val, getter, setter, flags) }
}