forked from denoland/deno
-
Notifications
You must be signed in to change notification settings - Fork 1
/
static.rs
138 lines (134 loc) · 4.55 KB
/
static.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use crate::dlfcn::DynamicLibraryResource;
use crate::symbol::NativeType;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::op2;
use deno_core::v8;
use deno_core::OpState;
use deno_core::ResourceId;
use std::ptr;
#[op2]
pub fn op_ffi_get_static<'scope>(
scope: &mut v8::HandleScope<'scope>,
state: &mut OpState,
#[smi] rid: ResourceId,
#[string] name: String,
#[serde] static_type: NativeType,
optional: bool,
) -> Result<v8::Local<'scope, v8::Value>, AnyError> {
let resource = state.resource_table.get::<DynamicLibraryResource>(rid)?;
let data_ptr = match resource.get_static(name) {
Ok(data_ptr) => Ok(data_ptr),
Err(err) => {
if optional {
let null: v8::Local<v8::Value> = v8::null(scope).into();
return Ok(null);
} else {
Err(err)
}
}
}?;
Ok(match static_type {
NativeType::Void => {
return Err(type_error("Invalid FFI static type 'void'"));
}
NativeType::Bool => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const bool) };
let boolean: v8::Local<v8::Value> =
v8::Boolean::new(scope, result).into();
boolean
}
NativeType::U8 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const u8) };
let number: v8::Local<v8::Value> =
v8::Integer::new_from_unsigned(scope, result as u32).into();
number
}
NativeType::I8 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const i8) };
let number: v8::Local<v8::Value> =
v8::Integer::new(scope, result as i32).into();
number
}
NativeType::U16 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const u16) };
let number: v8::Local<v8::Value> =
v8::Integer::new_from_unsigned(scope, result as u32).into();
number
}
NativeType::I16 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const i16) };
let number: v8::Local<v8::Value> =
v8::Integer::new(scope, result as i32).into();
number
}
NativeType::U32 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const u32) };
let number: v8::Local<v8::Value> =
v8::Integer::new_from_unsigned(scope, result).into();
number
}
NativeType::I32 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const i32) };
let number: v8::Local<v8::Value> = v8::Integer::new(scope, result).into();
number
}
NativeType::U64 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const u64) };
let integer: v8::Local<v8::Value> =
v8::BigInt::new_from_u64(scope, result).into();
integer
}
NativeType::I64 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const i64) };
let integer: v8::Local<v8::Value> =
v8::BigInt::new_from_i64(scope, result).into();
integer
}
NativeType::USize => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const usize) };
let integer: v8::Local<v8::Value> =
v8::BigInt::new_from_u64(scope, result as u64).into();
integer
}
NativeType::ISize => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const isize) };
let integer: v8::Local<v8::Value> =
v8::BigInt::new_from_i64(scope, result as i64).into();
integer
}
NativeType::F32 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const f32) };
let number: v8::Local<v8::Value> =
v8::Number::new(scope, result as f64).into();
number
}
NativeType::F64 => {
// SAFETY: ptr is user provided
let result = unsafe { ptr::read_unaligned(data_ptr as *const f64) };
let number: v8::Local<v8::Value> = v8::Number::new(scope, result).into();
number
}
NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
let external: v8::Local<v8::Value> =
v8::External::new(scope, data_ptr).into();
external
}
NativeType::Struct(_) => {
return Err(type_error("Invalid FFI static type 'struct'"));
}
})
}