deno.land / x / deno@v1.28.2 / cli / napi / js_native_api.rs
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
#![allow(non_upper_case_globals)]
use deno_runtime::deno_napi::*;use v8::BackingStore;use v8::UniqueRef;
use super::util::get_array_buffer_ptr;use deno_runtime::deno_napi::function::create_function;use deno_runtime::deno_napi::function::create_function_template;use deno_runtime::deno_napi::function::CallbackInfo;use std::ptr::NonNull;
// Macro to check napi arguments.// If nullptr, return Err(Error::InvalidArg).#[macro_export]macro_rules! check_arg { ($ptr: expr) => { if $ptr.is_null() { return Err(Error::InvalidArg); } };}
macro_rules! check_arg_option { ($ptr: expr) => { if $ptr.is_none() { return Err(Error::InvalidArg); } };}
/// Returns napi_value that represents a new JavaScript Array.#[napi_sym::napi_sym]fn napi_create_array(env: *mut Env, result: *mut napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg!(result);
let value = v8::Array::new(&mut env.scope(), 0); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_array_with_length( env: *mut Env, len: i32, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg!(result);
let value = v8::Array::new(&mut env.scope(), len); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_arraybuffer( env: *mut Env, len: usize, data: *mut *mut u8, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg!(result);
let value = v8::ArrayBuffer::new(&mut env.scope(), len); if !data.is_null() { *data = get_array_buffer_ptr(value); }
*result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_bigint_int64( env: *mut Env, value: i64, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg!(result);
let value = v8::BigInt::new_from_i64(&mut env.scope(), value); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_bigint_uint64( env: *mut Env, value: u64, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::BigInt::new_from_u64(&mut env.scope(), value).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_bigint_words( env: *mut Env, sign_bit: bool, words: *const u64, word_count: usize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::BigInt::new_from_words( &mut env.scope(), sign_bit, std::slice::from_raw_parts(words, word_count), ) .unwrap() .into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_buffer( env: *mut Env, len: usize, data: *mut *mut u8, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = v8::ArrayBuffer::new(&mut env.scope(), len); if !data.is_null() { *data = get_array_buffer_ptr(value); } let value = v8::Uint8Array::new(&mut env.scope(), value, 0, len).unwrap(); let value: v8::Local<v8::Value> = value.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_buffer_copy( env: *mut Env, len: usize, data: *mut u8, result_data: *mut *mut u8, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = v8::ArrayBuffer::new(&mut env.scope(), len); let ptr = get_array_buffer_ptr(value); std::ptr::copy(data, ptr, len); if !result_data.is_null() { *result_data = ptr; } let value = v8::Uint8Array::new(&mut env.scope(), value, 0, len).unwrap(); let value: v8::Local<v8::Value> = value.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_coerce_to_bool( env: *mut Env, value: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let coerced = value.to_boolean(&mut env.scope()); let value: v8::Local<v8::Value> = coerced.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_coerce_to_number( env: *mut Env, value: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let coerced = value .to_number(&mut env.scope()) .ok_or(Error::NumberExpected)?; let value: v8::Local<v8::Value> = coerced.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_coerce_to_object( env: *mut Env, value: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let coerced = value.to_object(&mut env.scope()).unwrap(); let value: v8::Local<v8::Value> = coerced.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_coerce_to_string( env: *mut Env, value: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let coerced = value.to_string(&mut env.scope()).unwrap(); let value: v8::Local<v8::Value> = coerced.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_dataview( env: *mut Env, len: usize, data: *mut *mut u8, byte_offset: usize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg!(data); check_arg!(result); let value = v8::ArrayBuffer::new(&mut env.scope(), len); if !data.is_null() { *data = get_array_buffer_ptr(value); } let context = &mut env.scope().get_current_context(); let global = context.global(&mut env.scope()); let data_view_name = v8::String::new(&mut env.scope(), "DataView").unwrap(); let data_view = global.get(&mut env.scope(), data_view_name.into()).unwrap(); let data_view = v8::Local::<v8::Function>::try_from(data_view).unwrap(); let byte_offset = v8::Number::new(&mut env.scope(), byte_offset as f64); let byte_length = v8::Number::new(&mut env.scope(), len as f64); let value = data_view .new_instance( &mut env.scope(), &[value.into(), byte_offset.into(), byte_length.into()], ) .unwrap(); let value: v8::Local<v8::Value> = value.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_date( env: *mut Env, time: f64, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Date::new(&mut env.scope(), time).unwrap().into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_double( env: *mut Env, value: f64, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Number::new(&mut env.scope(), value).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_error( env: *mut Env, code: napi_value, msg: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let _code = transmute::<napi_value, v8::Local<v8::Value>>(code); let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
let msg = msg.to_string(&mut env.scope()).unwrap();
let error = v8::Exception::error(&mut env.scope(), msg); *result = error.into();
Ok(())}
#[napi_sym::napi_sym]fn napi_create_external( env: *mut Env, value: *mut c_void, _finalize_cb: napi_finalize, _finalize_hint: *mut c_void, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::External::new(&mut env.scope(), value).into(); // TODO: finalization *result = value.into(); Ok(())}
pub type BackingStoreDeleterCallback = unsafe extern "C" fn( data: *mut c_void, byte_length: usize, deleter_data: *mut c_void,);extern "C" { fn v8__ArrayBuffer__NewBackingStore__with_data( data: *mut c_void, byte_length: usize, deleter: BackingStoreDeleterCallback, deleter_data: *mut c_void, ) -> *mut BackingStore;}
pub extern "C" fn backing_store_deleter_callback( data: *mut c_void, byte_length: usize, _deleter_data: *mut c_void,) { let slice_ptr = ptr::slice_from_raw_parts_mut(data as *mut u8, byte_length); let b = unsafe { Box::from_raw(slice_ptr) }; drop(b);}
#[napi_sym::napi_sym]fn napi_create_external_arraybuffer( env: *mut Env, data: *mut c_void, byte_length: usize, _finalize_cb: napi_finalize, finalize_hint: *mut c_void, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let _slice = std::slice::from_raw_parts(data as *mut u8, byte_length); // TODO: finalization let store: UniqueRef<BackingStore> = transmute(v8__ArrayBuffer__NewBackingStore__with_data( data, byte_length, backing_store_deleter_callback, finalize_hint, ));
let ab = v8::ArrayBuffer::with_backing_store(&mut env.scope(), &store.make_shared()); let value: v8::Local<v8::Value> = ab.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_external_buffer( env: *mut Env, byte_length: isize, data: *mut c_void, _finalize_cb: napi_finalize, _finalize_hint: *mut c_void, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let slice = if byte_length == -1 { std::ffi::CStr::from_ptr(data as *const _).to_bytes() } else { std::slice::from_raw_parts(data as *mut u8, byte_length as usize) }; // TODO: make this not copy the slice // TODO: finalization let store = v8::ArrayBuffer::new_backing_store_from_boxed_slice( slice.to_vec().into_boxed_slice(), ); let ab = v8::ArrayBuffer::with_backing_store(&mut env.scope(), &store.make_shared()); let value = v8::Uint8Array::new(&mut env.scope(), ab, 0, slice.len()).unwrap(); let value: v8::Local<v8::Value> = value.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_function( env_ptr: *mut Env, name: *const u8, length: isize, cb: napi_callback, cb_info: napi_callback_info, result: *mut napi_value,) -> Result { let _: &mut Env = env_ptr.as_mut().ok_or(Error::InvalidArg)?; let name = match name.is_null() { true => None, false => Some(name), }; let name = name.map(|name| { if length == -1 { std::ffi::CStr::from_ptr(name as *const _).to_str().unwrap() } else { let name = std::slice::from_raw_parts(name, length as usize); // If ends with NULL if name[name.len() - 1] == 0 { std::str::from_utf8(&name[0..name.len() - 1]).unwrap() } else { std::str::from_utf8(name).unwrap() } } });
let function = create_function(env_ptr, name, cb, cb_info); let value: v8::Local<v8::Value> = function.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_int32( env: *mut Env, value: i32, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Number::new(&mut env.scope(), value as f64).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_int64( env: *mut Env, value: i64, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Number::new(&mut env.scope(), value as f64).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_object(env: *mut Env, result: *mut napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = v8::Object::new(&mut env.scope()); *result = object.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_promise( env: *mut Env, deferred: *mut napi_deferred, promise_out: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let resolver = v8::PromiseResolver::new(&mut env.scope()).unwrap(); let mut global = v8::Global::new(&mut env.scope(), resolver); let mut global_ptr = global.into_raw(); let promise = resolver.get_promise(&mut env.scope()); *deferred = global_ptr.as_mut() as *mut _ as napi_deferred; *promise_out = promise.into();
Ok(())}
#[napi_sym::napi_sym]fn napi_create_range_error( env: *mut Env, _code: napi_value, msg: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = transmute::<napi_value, v8::Local<v8::Value>>(code); let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
let msg = msg.to_string(&mut env.scope()).unwrap();
let error = v8::Exception::range_error(&mut env.scope(), msg); *result = error.into();
Ok(())}
#[napi_sym::napi_sym]fn napi_create_reference( env: *mut Env, value: napi_value, _initial_refcount: u32, result: *mut napi_ref,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let global = v8::Global::new(&mut env.scope(), value); let mut global_ptr = global.into_raw(); *result = transmute::<NonNull<v8::Value>, napi_ref>(global_ptr); Ok(())}
#[napi_sym::napi_sym]fn napi_create_string_latin1( env: *mut Env, string: *const u8, length: isize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let string = if length == -1 { std::ffi::CStr::from_ptr(string as *const _) .to_str() .unwrap() .as_bytes() } else { std::slice::from_raw_parts(string, length as usize) }; match v8::String::new_from_one_byte( &mut env.scope(), string, v8::NewStringType::Normal, ) { Some(v8str) => { let value: v8::Local<v8::Value> = v8str.into(); *result = value.into(); } None => return Err(Error::GenericFailure), }
Ok(())}
#[napi_sym::napi_sym]fn napi_create_string_utf16( env: *mut Env, string: *const u16, length: usize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let string = std::slice::from_raw_parts(string, length); let v8str = v8::String::new_from_two_byte( &mut env.scope(), string, v8::NewStringType::Normal, ) .unwrap(); let value: v8::Local<v8::Value> = v8str.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_string_utf8( env: *mut Env, string: *const u8, length: isize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let string = if length == -1 { std::ffi::CStr::from_ptr(string as *const _) .to_str() .unwrap() } else { let string = std::slice::from_raw_parts(string, length as usize); std::str::from_utf8(string).unwrap() }; let v8str = v8::String::new(&mut env.scope(), string).unwrap(); let value: v8::Local<v8::Value> = v8str.into(); *result = value.into();
Ok(())}
#[napi_sym::napi_sym]fn napi_create_symbol( env: *mut Env, description: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let description = match description.is_none() { true => None, false => Some( transmute::<napi_value, v8::Local<v8::Value>>(description) .to_string(&mut env.scope()) .unwrap(), ), }; let sym = v8::Symbol::new(&mut env.scope(), description); *result = sym.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_type_error( env: *mut Env, _code: napi_value, msg: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = transmute::<napi_value, v8::Local<v8::Value>>(code); let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
let msg = msg.to_string(&mut env.scope()).unwrap();
let error = v8::Exception::type_error(&mut env.scope(), msg); *result = error.into();
Ok(())}
#[napi_sym::napi_sym]fn napi_create_typedarray( env: *mut Env, ty: napi_typedarray_type, length: usize, arraybuffer: napi_value, byte_offset: usize, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let ab = transmute::<napi_value, v8::Local<v8::Value>>(arraybuffer); let ab = v8::Local::<v8::ArrayBuffer>::try_from(ab).unwrap(); let typedarray: v8::Local<v8::Value> = match ty { napi_uint8_array => { v8::Uint8Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_uint8_clamped_array => { v8::Uint8ClampedArray::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_int8_array => { v8::Int8Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_uint16_array => { v8::Uint16Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_int16_array => { v8::Int16Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_uint32_array => { v8::Uint32Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_int32_array => { v8::Int32Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_float32_array => { v8::Float32Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_float64_array => { v8::Float64Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_bigint64_array => { v8::BigInt64Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } napi_biguint64_array => { v8::BigUint64Array::new(&mut env.scope(), ab, byte_offset, length) .unwrap() .into() } _ => { return Err(Error::InvalidArg); } }; *result = typedarray.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_create_uint32( env: *mut Env, value: u32, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Number::new(&mut env.scope(), value as f64).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_make_callback( env: *mut Env, async_context: *mut c_void, recv: napi_value, func: napi_value, argc: isize, argv: *const napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg_option!(recv); if argc > 0 { check_arg!(argv); }
if !async_context.is_null() { eprintln!("napi_make_callback: async_context is not supported"); }
let recv = transmute::<napi_value, v8::Local<v8::Value>>(recv); let func = transmute::<napi_value, v8::Local<v8::Value>>(func);
let func = v8::Local::<v8::Function>::try_from(func) .map_err(|_| Error::FunctionExpected)?; let argv: &[v8::Local<v8::Value>] = transmute(std::slice::from_raw_parts(argv, argc as usize)); let ret = func.call(&mut env.scope(), recv, argv); *result = transmute::<Option<v8::Local<v8::Value>>, napi_value>(ret); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_bigint_int64( env: *mut Env, value: napi_value, result: *mut i64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let bigint = value.to_big_int(&mut env.scope()).unwrap(); *result = bigint.i64_value().0; Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_bigint_uint64( env: *mut Env, value: napi_value, result: *mut u64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let bigint = value.to_big_int(&mut env.scope()).unwrap(); *result = bigint.u64_value().0; Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_bigint_words( env: *mut Env, value: napi_value, sign_bit: *mut i32, size: *mut usize, out_words: *mut u64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let bigint = value.to_big_int(&mut env.scope()).unwrap();
let out_words = std::slice::from_raw_parts_mut(out_words, *size); let mut words = Vec::with_capacity(bigint.word_count()); let (sign, _) = bigint.to_words_array(words.as_mut_slice()); *sign_bit = sign as i32;
for (i, word) in out_words.iter_mut().enumerate() { *word = words[i]; }
Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_bool( env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.boolean_value(&mut env.scope()); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_double( env: *mut Env, value: napi_value, result: *mut f64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.number_value(&mut env.scope()).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_external( _env: *mut Env, value: napi_value, result: *mut *mut c_void,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let ext = v8::Local::<v8::External>::try_from(value).unwrap(); *result = ext.value(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_int32( env: *mut Env, value: napi_value, result: *mut i32,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.int32_value(&mut env.scope()).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_int64( env: *mut Env, value: napi_value, result: *mut i64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.integer_value(&mut env.scope()).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_string_latin1( env: *mut Env, value: napi_value, buf: *mut u8, bufsize: usize, result: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_value, v8::Local<v8::Value>>(value);
if !value.is_string() && !value.is_string_object() { return Err(Error::StringExpected); }
let v8str = value.to_string(&mut env.scope()).unwrap(); let string_len = v8str.utf8_length(&mut env.scope());
if buf.is_null() { *result = string_len; } else if bufsize != 0 { let buffer = std::slice::from_raw_parts_mut(buf, bufsize - 1); let copied = v8str.write_one_byte( &mut env.scope(), buffer, 0, v8::WriteOptions::NO_NULL_TERMINATION, ); buf.add(copied).write(0); if !result.is_null() { *result = copied; } } else if !result.is_null() { *result = string_len; }
Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_string_utf8( env: *mut Env, value: napi_value, buf: *mut u8, bufsize: usize, result: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_value, v8::Local<v8::Value>>(value);
if !value.is_string() && !value.is_string_object() { return Err(Error::StringExpected); }
let v8str = value.to_string(&mut env.scope()).unwrap(); let string_len = v8str.utf8_length(&mut env.scope());
if buf.is_null() { *result = string_len; } else if bufsize != 0 { let buffer = std::slice::from_raw_parts_mut(buf, bufsize - 1); let copied = v8str.write_utf8( &mut env.scope(), buffer, None, v8::WriteOptions::NO_NULL_TERMINATION | v8::WriteOptions::REPLACE_INVALID_UTF8, ); buf.add(copied).write(0); if !result.is_null() { *result = copied; } } else if !result.is_null() { *result = string_len; }
Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_string_utf16( env: *mut Env, value: napi_value, buf: *mut u16, bufsize: usize, result: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_value, v8::Local<v8::Value>>(value);
if !value.is_string() && !value.is_string_object() { return Err(Error::StringExpected); }
let v8str = value.to_string(&mut env.scope()).unwrap(); let string_len = v8str.length();
if buf.is_null() { *result = string_len; } else if bufsize != 0 { let buffer = std::slice::from_raw_parts_mut(buf, bufsize - 1); let copied = v8str.write( &mut env.scope(), buffer, 0, v8::WriteOptions::NO_NULL_TERMINATION, ); buf.add(copied).write(0); if !result.is_null() { *result = copied; } } else if !result.is_null() { *result = string_len; }
Ok(())}
#[napi_sym::napi_sym]fn napi_get_value_uint32( env: *mut Env, value: napi_value, result: *mut u32,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.uint32_value(&mut env.scope()).unwrap(); Ok(())}
// TODO#[napi_sym::napi_sym]fn napi_add_finalizer( _env: *mut Env, _js_object: napi_value, _native_object: *const c_void, _finalize_cb: napi_finalize, _finalize_hint: *const c_void, _result: *mut napi_ref,) -> Result { eprintln!("napi_add_finalizer is not yet supported."); Ok(())}
#[napi_sym::napi_sym]fn napi_adjust_external_memory( env: *mut Env, change_in_bytes: i64, adjusted_value: &mut i64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let isolate = &mut *env.isolate_ptr; *adjusted_value = isolate.adjust_amount_of_external_allocated_memory(change_in_bytes); Ok(())}
#[napi_sym::napi_sym]fn napi_call_function( env: *mut Env, recv: napi_value, func: napi_value, argc: usize, argv: *const napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let recv = transmute::<napi_value, v8::Local<v8::Value>>(recv); let func = transmute::<napi_value, v8::Local<v8::Value>>(func); let func = v8::Local::<v8::Function>::try_from(func) .map_err(|_| Error::FunctionExpected)?;
let argv: &[v8::Local<v8::Value>] = transmute(std::slice::from_raw_parts(argv, argc as usize)); let ret = func.call(&mut env.scope(), recv, argv); if !result.is_null() { *result = transmute::<Option<v8::Local<v8::Value>>, napi_value>(ret); }
Ok(())}
#[napi_sym::napi_sym]fn napi_close_escapable_handle_scope( env: *mut Env, _scope: napi_escapable_handle_scope,) -> Result { let mut _env = &mut *(env as *mut Env); // TODO: do this properly Ok(())}
#[napi_sym::napi_sym]fn napi_close_handle_scope(env: *mut Env, scope: napi_handle_scope) -> Result { let env = &mut *(env as *mut Env); if env.open_handle_scopes == 0 { return Err(Error::HandleScopeMismatch); } let _scope = &mut *(scope as *mut v8::HandleScope); env.open_handle_scopes -= 1; Ok(())}
#[napi_sym::napi_sym]fn napi_define_class( env_ptr: *mut Env, name: *const c_char, length: isize, constructor: napi_callback, callback_data: *mut c_void, property_count: usize, properties: *const napi_property_descriptor, result: *mut napi_value,) -> Result { let env: &mut Env = env_ptr.as_mut().ok_or(Error::InvalidArg)?; check_arg!(result); // check_arg!(constructor as *const c_void);
if property_count > 0 { check_arg!(properties); }
let name = if length == -1 { std::ffi::CStr::from_ptr(name) .to_str() .map_err(|_| Error::InvalidArg)? } else { let slice = std::slice::from_raw_parts(name as *const u8, length as usize); std::str::from_utf8(slice).unwrap() };
let tpl = create_function_template(env_ptr, Some(name), constructor, callback_data);
let scope = &mut env.scope(); let napi_properties: &[napi_property_descriptor] = std::slice::from_raw_parts(properties, property_count);
for p in napi_properties { let name = if !p.utf8name.is_null() { let name_str = CStr::from_ptr(p.utf8name).to_str().unwrap(); v8::String::new(scope, name_str).unwrap() } else { transmute::<napi_value, v8::Local<v8::String>>(p.name) };
let method = p.method; let getter = p.getter; let setter = p.setter;
if getter.is_some() || setter.is_some() { let getter: Option<v8::Local<v8::FunctionTemplate>> = if getter.is_some() { Some(create_function_template(env_ptr, None, p.getter, p.data)) } else { None }; let setter: Option<v8::Local<v8::FunctionTemplate>> = if setter.is_some() { Some(create_function_template(env_ptr, None, p.setter, p.data)) } else { None };
let mut accessor_property = v8::NONE; if getter.is_some() && setter.is_some() && (p.attributes & napi_writable) == 0 { accessor_property = accessor_property | v8::READ_ONLY; } if p.attributes & napi_enumerable == 0 { accessor_property = accessor_property | v8::DONT_ENUM; } if p.attributes & napi_configurable == 0 { accessor_property = accessor_property | v8::DONT_DELETE; }
let proto = tpl.prototype_template(scope); proto.set_accessor_property( name.into(), getter, setter, accessor_property, );
// // TODO: use set_accessor & set_accessor_with_setter // match (getter, setter) { // (Some(getter), None) => { // proto.set(name.into(), getter.into()); // } // (Some(getter), Some(setter)) => { // proto.set(name.into(), getter.into()); // proto.set(name.into(), setter.into()); // } // (None, Some(setter)) => { // proto.set(name.into(), setter.into()); // } // (None, None) => unreachable!(), // } } else if method.is_some() { let function = create_function_template(env_ptr, None, p.method, p.data); let proto = tpl.prototype_template(scope); proto.set(name.into(), function.into()); } else { let proto = tpl.prototype_template(scope); proto.set( name.into(), transmute::<napi_value, v8::Local<v8::Data>>(p.value), ); } }
let value: v8::Local<v8::Value> = tpl.get_function(scope).unwrap().into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_define_properties( env_ptr: *mut Env, obj: napi_value, property_count: usize, properties: *const napi_property_descriptor,) -> Result { let env: &mut Env = env_ptr.as_mut().ok_or(Error::InvalidArg)?; let scope = &mut env.scope(); let object = transmute::<napi_value, v8::Local<v8::Object>>(obj); let properties = std::slice::from_raw_parts(properties, property_count);
for property in properties { let name = if !property.utf8name.is_null() { let name_str = CStr::from_ptr(property.utf8name).to_str().unwrap(); v8::String::new(scope, name_str).unwrap() } else { transmute::<napi_value, v8::Local<v8::String>>(property.name) };
let method_ptr = property.method;
if method_ptr.is_some() { let function: v8::Local<v8::Value> = { let function = create_function(env_ptr, None, property.method, property.data); function.into() }; object.set(scope, name.into(), function).unwrap(); } }
Ok(())}
#[napi_sym::napi_sym]fn napi_delete_element( env: *mut Env, value: napi_value, index: u32, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); *result = obj.delete_index(&mut env.scope(), index).unwrap_or(false); Ok(())}
#[napi_sym::napi_sym]fn napi_delete_property( env: *mut Env, value: napi_value, key: napi_value, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); *result = obj .delete( &mut env.scope(), transmute::<napi_value, v8::Local<v8::Value>>(key), ) .unwrap_or(false); Ok(())}
// TODO: properly implement ref counting stuff#[napi_sym::napi_sym]fn napi_delete_reference(env: *mut Env, _nref: napi_ref) -> Result { let mut _env = &mut *(env as *mut Env); Ok(())}
#[napi_sym::napi_sym]fn napi_detach_arraybuffer(env: *mut Env, value: napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let ab = v8::Local::<v8::ArrayBuffer>::try_from(value).unwrap(); ab.detach(v8::undefined(&mut env.scope()).into()); Ok(())}
#[napi_sym::napi_sym]fn napi_escape_handle<'s>( _env: *mut Env, _handle_scope: napi_escapable_handle_scope, escapee: napi_value<'s>, result: *mut napi_value<'s>,) -> Result { // TODO *result = escapee; Ok(())}
#[napi_sym::napi_sym]fn napi_get_all_property_names(_env: *mut Env) -> Result { // TODO Ok(())}
#[napi_sym::napi_sym]fn napi_get_and_clear_last_exception( env: *mut Env, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; // TODO: just return undefined for now we don't cache // exceptions in env. let value: v8::Local<v8::Value> = v8::undefined(&mut env.scope()).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_array_length( _env: *mut Env, value: napi_value, result: *mut u32,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = v8::Local::<v8::Array>::try_from(value).unwrap().length(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_arraybuffer_info( _env: *mut Env, value: napi_value, data: *mut *mut u8, length: *mut usize,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let buf = v8::Local::<v8::ArrayBuffer>::try_from(value).unwrap(); if !data.is_null() { *data = get_array_buffer_ptr(buf); } *length = buf.byte_length(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_boolean( env: *mut Env, value: bool, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::Boolean::new(env.isolate(), value).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_buffer_info( env: *mut Env, value: napi_value, data: *mut *mut u8, length: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let buf = v8::Local::<v8::Uint8Array>::try_from(value).unwrap(); let buffer_name = v8::String::new(&mut env.scope(), "buffer").unwrap(); let abuf = v8::Local::<v8::ArrayBuffer>::try_from( buf.get(&mut env.scope(), buffer_name.into()).unwrap(), ) .unwrap(); if !data.is_null() { *data = get_array_buffer_ptr(abuf); } *length = abuf.byte_length(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_cb_info( _env: *mut Env, cbinfo: napi_callback_info, argc: *mut i32, argv: *mut napi_value, this_arg: *mut napi_value, cb_data: *mut *mut c_void,) -> Result { let cbinfo: &CallbackInfo = &*(cbinfo as *const CallbackInfo); let args = &*(cbinfo.args as *const v8::FunctionCallbackArguments);
if !cb_data.is_null() { *cb_data = cbinfo.cb_info; }
if !this_arg.is_null() { let mut this = args.this(); *this_arg = this.into(); }
let len = args.length(); let mut v_argc = len; if !argc.is_null() { *argc = len; }
if !argv.is_null() { let mut v_argv = std::slice::from_raw_parts_mut(argv, v_argc as usize); for i in 0..v_argc { let mut arg = args.get(i); v_argv[i as usize] = arg.into(); } }
Ok(())}
#[napi_sym::napi_sym]fn napi_get_dataview_info( env: *mut Env, value: napi_value, data: *mut *mut u8, length: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let buf = v8::Local::<v8::DataView>::try_from(value).unwrap(); let buffer_name = v8::String::new(&mut env.scope(), "buffer").unwrap(); let abuf = v8::Local::<v8::ArrayBuffer>::try_from( buf.get(&mut env.scope(), buffer_name.into()).unwrap(), ) .unwrap(); if !data.is_null() { *data = get_array_buffer_ptr(abuf); } *length = abuf.byte_length(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_date_value( env: *mut Env, value: napi_value, result: *mut f64,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let date = v8::Local::<v8::Date>::try_from(value).unwrap(); *result = date.number_value(&mut env.scope()).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_element( env: *mut Env, object: napi_value, index: u32, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Value>>(object); let array = v8::Local::<v8::Array>::try_from(object).unwrap(); let value: v8::Local<v8::Value> = array.get_index(&mut env.scope(), index).unwrap(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_global(env: *mut Env, result: *mut napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let context = &mut env.scope().get_current_context(); let global = context.global(&mut env.scope()); let value: v8::Local<v8::Value> = global.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_instance_data(env: *mut Env, result: *mut *mut c_void) -> Result { let env = &mut *(env as *mut Env); let shared = env.shared(); *result = shared.instance_data; Ok(())}
#[napi_sym::napi_sym]fn napi_get_last_error_info( _env: *mut Env, error_code: *mut *const napi_extended_error_info,) -> Result { let err_info = Box::new(napi_extended_error_info { error_message: std::ptr::null(), engine_reserved: std::ptr::null_mut(), engine_error_code: 0, status_code: napi_ok, });
*error_code = Box::into_raw(err_info); Ok(())}
#[napi_sym::napi_sym]fn napi_get_named_property( env: *mut Env, object: napi_value, utf8_name: *const c_char, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Value>>(object); let utf8_name = std::ffi::CStr::from_ptr(utf8_name); let name = v8::String::new(&mut env.scope(), &utf8_name.to_string_lossy()).unwrap(); let value: v8::Local<v8::Value> = object .to_object(&mut env.scope()) .unwrap() .get(&mut env.scope(), name.into()) .unwrap(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_new_target( _env: &mut Env, cbinfo: &CallbackInfo, result: &mut v8::Local<v8::Value>,) -> Result { let info = &*(cbinfo.args as *const v8::FunctionCallbackArguments); *result = info.new_target(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_null(env: *mut Env, result: *mut napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value: v8::Local<v8::Value> = v8::null(env.isolate()).into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_property( env: *mut Env, object: napi_value, key: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Object>>(object); let key = transmute::<napi_value, v8::Local<v8::Value>>(key); let value: v8::Local<v8::Value> = object.get(&mut env.scope(), key).unwrap(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_property_names( env: *mut Env, object: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Value>>(object); let array: v8::Local<v8::Array> = object .to_object(&mut env.scope()) .unwrap() .get_property_names(&mut env.scope(), Default::default()) .unwrap(); let value: v8::Local<v8::Value> = array.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_prototype( env: *mut Env, value: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); let proto = obj.get_prototype(&mut env.scope()).unwrap(); *result = proto.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_reference_value( env: *mut Env, reference: napi_ref, result: *mut napi_value,) -> Result { // TODO let _env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let value = transmute::<napi_ref, v8::Local<v8::Value>>(reference); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_typedarray_info( env: *mut Env, value: napi_value, data: *mut *mut u8, length: *mut usize,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let buf = v8::Local::<v8::TypedArray>::try_from(value).unwrap(); let buffer_name = v8::String::new(&mut env.scope(), "buffer").unwrap(); let abuf = v8::Local::<v8::ArrayBuffer>::try_from( buf.get(&mut env.scope(), buffer_name.into()).unwrap(), ) .unwrap(); if !data.is_null() { *data = get_array_buffer_ptr(abuf); } *length = abuf.byte_length(); Ok(())}
#[napi_sym::napi_sym]fn napi_get_undefined(env: *mut Env, result: *mut napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value: v8::Local<v8::Value> = v8::undefined(env.isolate()).into(); *result = value.into(); Ok(())}
pub const NAPI_VERSION: u32 = 8;
#[napi_sym::napi_sym]fn napi_get_version(_: napi_env, version: *mut u32) -> Result { *version = NAPI_VERSION; Ok(())}
#[napi_sym::napi_sym]fn napi_has_element( env: *mut Env, value: napi_value, index: u32, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); *result = obj.has_index(&mut env.scope(), index).unwrap_or(false); Ok(())}
#[napi_sym::napi_sym]fn napi_has_named_property( env: *mut Env, value: napi_value, key: *const c_char, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); let key = CStr::from_ptr(key).to_str().unwrap(); let key = v8::String::new(&mut env.scope(), key).unwrap(); *result = obj.has(&mut env.scope(), key.into()).unwrap_or(false); Ok(())}
#[napi_sym::napi_sym]fn napi_has_own_property( env: *mut Env, object: napi_value, key: napi_value, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(object); let object = value.to_object(&mut env.scope()).unwrap();
let key = transmute::<napi_value, v8::Local<v8::Value>>(key); if !key.is_name() { return Err(Error::NameExpected); }
let maybe = object .has_own_property( &mut env.scope(), v8::Local::<v8::Name>::try_from(key).unwrap(), ) .unwrap_or(false);
*result = maybe; if !maybe { return Err(Error::GenericFailure); }
Ok(())}
#[napi_sym::napi_sym]fn napi_has_property( env: *mut Env, value: napi_value, key: napi_value, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); *result = obj .has( &mut env.scope(), transmute::<napi_value, v8::Local<v8::Value>>(key), ) .unwrap_or(false); Ok(())}
#[napi_sym::napi_sym]fn napi_instanceof( env: *mut Env, value: napi_value, constructor: napi_value, result: *mut bool,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; check_arg_option!(constructor); check_arg_option!(value);
let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let constructor = transmute::<napi_value, v8::Local<v8::Value>>(constructor); let ctor = constructor .to_object(&mut env.scope()) .ok_or(Error::ObjectExpected)?; if !ctor.is_function() { return Err(Error::FunctionExpected); } let maybe = value.instance_of(&mut env.scope(), ctor); match maybe { Some(res) => { *result = res; Ok(()) } None => Err(Error::GenericFailure), }}
#[napi_sym::napi_sym]fn napi_is_array( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_array(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_arraybuffer( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_array_buffer(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_buffer( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); // TODO: should we assume Buffer as Uint8Array in Deno? // or use std/node polyfill? *result = value.is_typed_array(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_dataview( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_data_view(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_date( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_date(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_detached_arraybuffer( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let _ab = v8::Local::<v8::ArrayBuffer>::try_from(value).unwrap(); *result = _ab.was_detached(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_error( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); // TODO *result = value.is_object(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_exception_pending(env: *mut Env, result: *mut bool) -> Result { let mut _env = &mut *(env as *mut Env); // TODO *result = false; Ok(())}
#[napi_sym::napi_sym]fn napi_is_promise( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_promise(); Ok(())}
#[napi_sym::napi_sym]fn napi_is_typedarray( _env: *mut Env, value: napi_value, result: *mut bool,) -> Result { let value = transmute::<napi_value, v8::Local<v8::Value>>(value); *result = value.is_typed_array(); Ok(())}
#[napi_sym::napi_sym]fn napi_new_instance( env: *mut Env, constructor: napi_value, argc: usize, argv: *const napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let constructor = transmute::<napi_value, v8::Local<v8::Value>>(constructor); let constructor = v8::Local::<v8::Function>::try_from(constructor).unwrap(); let args: &[v8::Local<v8::Value>] = transmute(std::slice::from_raw_parts(argv, argc)); let inst = constructor.new_instance(&mut env.scope(), args).unwrap(); let value: v8::Local<v8::Value> = inst.into(); *result = value.into(); Ok(())}
#[napi_sym::napi_sym]fn napi_object_freeze(env: &mut Env, object: v8::Local<v8::Value>) -> Result { let object = object.to_object(&mut env.scope()).unwrap(); let maybe = object.set_integrity_level(&mut env.scope(), v8::IntegrityLevel::Frozen);
match maybe { Some(_) => Ok(()), None => Err(Error::GenericFailure), }}
#[napi_sym::napi_sym]fn napi_object_seal(env: &mut Env, object: v8::Local<v8::Value>) -> Result { let object = object.to_object(&mut env.scope()).unwrap(); let maybe = object.set_integrity_level(&mut env.scope(), v8::IntegrityLevel::Sealed);
match maybe { Some(_) => Ok(()), None => Err(Error::GenericFailure), }}
#[napi_sym::napi_sym]fn napi_open_escapable_handle_scope( _env: *mut Env, _result: *mut napi_escapable_handle_scope,) -> Result { // TODO: do this properly Ok(())}
#[napi_sym::napi_sym]fn napi_open_handle_scope( env: *mut Env, _result: *mut napi_handle_scope,) -> Result { let env = &mut *(env as *mut Env);
// *result = &mut env.scope() as *mut _ as napi_handle_scope; env.open_handle_scopes += 1; Ok(())}
#[napi_sym::napi_sym]fn napi_reference_ref() -> Result { // TODO Ok(())}
#[napi_sym::napi_sym]fn napi_reference_unref() -> Result { // TODO Ok(())}
#[napi_sym::napi_sym]fn napi_reject_deferred( env: *mut Env, deferred: napi_deferred, error: napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let deferred_ptr = NonNull::new_unchecked(deferred as *mut v8::PromiseResolver); // TODO(@littledivy): Use Global::from_raw instead casting to local. // SAFETY: Isolate is still alive unless the module is doing something weird, // global data is the size of a pointer. // Global pointer is obtained from napi_create_promise let resolver = transmute::< NonNull<v8::PromiseResolver>, v8::Local<v8::PromiseResolver>, >(deferred_ptr); resolver .reject( &mut env.scope(), transmute::<napi_value, v8::Local<v8::Value>>(error), ) .unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_remove_wrap(env: *mut Env, value: napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); let shared = &*(env.shared as *const EnvShared); let napi_wrap = v8::Local::new(&mut env.scope(), &shared.napi_wrap); obj.delete_private(&mut env.scope(), napi_wrap).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_resolve_deferred( env: *mut Env, deferred: napi_deferred, result: napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let deferred_ptr = NonNull::new_unchecked(deferred as *mut v8::PromiseResolver); // TODO(@littledivy): Use Global::from_raw instead casting to local. // SAFETY: Isolate is still alive unless the module is doing something weird, // global data is the size of a pointer. // Global pointer is obtained from napi_create_promise let resolver = transmute::< NonNull<v8::PromiseResolver>, v8::Local<v8::PromiseResolver>, >(deferred_ptr); resolver .resolve( &mut env.scope(), transmute::<napi_value, v8::Local<v8::Value>>(result), ) .unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_run_script( env: *mut Env, script: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
let script = transmute::<napi_value, v8::Local<v8::Value>>(script); if !script.is_string() { return Err(Error::StringExpected); } let script = script.to_string(&mut env.scope()).unwrap();
let script = v8::Script::compile(&mut env.scope(), script, None); if script.is_none() { return Err(Error::GenericFailure); } let script = script.unwrap(); let rv = script.run(&mut env.scope());
if let Some(rv) = rv { *result = rv.into(); } else { return Err(Error::GenericFailure); }
Ok(())}
#[napi_sym::napi_sym]fn napi_set_element( env: *mut Env, object: napi_value, index: u32, value: napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Value>>(object); let array = v8::Local::<v8::Array>::try_from(object).unwrap(); let value = transmute::<napi_value, v8::Local<v8::Value>>(value); array.set_index(&mut env.scope(), index, value).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_set_instance_data( env: *mut Env, data: *mut c_void, finalize_cb: napi_finalize, finalize_hint: *mut c_void,) -> Result { let env = &mut *(env as *mut Env); let shared = env.shared_mut(); shared.instance_data = data; shared.data_finalize = if !(finalize_cb as *const c_void).is_null() { Some(finalize_cb) } else { None }; shared.data_finalize_hint = finalize_hint; Ok(())}
#[napi_sym::napi_sym]fn napi_set_named_property( env: *mut Env, object: napi_value, name: *const c_char, value: napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let name = CStr::from_ptr(name).to_str().unwrap(); let object = transmute::<napi_value, v8::Local<v8::Object>>(object); let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let name = v8::String::new(&mut env.scope(), name).unwrap(); object.set(&mut env.scope(), name.into(), value).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_set_property( env: *mut Env, object: napi_value, property: napi_value, value: napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let object = transmute::<napi_value, v8::Local<v8::Value>>(object); let object = object.to_object(&mut env.scope()).unwrap(); let property = transmute::<napi_value, v8::Local<v8::Value>>(property); let value = transmute::<napi_value, v8::Local<v8::Value>>(value); object.set(&mut env.scope(), property, value).unwrap(); Ok(())}
#[napi_sym::napi_sym]fn napi_strict_equals( _env: *mut Env, lhs: napi_value, rhs: napi_value, result: *mut bool,) -> Result { let lhs = transmute::<napi_value, v8::Local<v8::Value>>(lhs); let rhs = transmute::<napi_value, v8::Local<v8::Value>>(rhs); *result = lhs.strict_equals(rhs); Ok(())}
#[napi_sym::napi_sym]fn napi_throw(env: *mut Env, error: napi_value) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let error = transmute::<napi_value, v8::Local<v8::Value>>(error); env.scope().throw_exception(error); Ok(())}
#[napi_sym::napi_sym]fn napi_throw_error( env: *mut Env, _code: *const c_char, msg: *const c_char,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = CStr::from_ptr(code).to_str().unwrap(); let msg = CStr::from_ptr(msg).to_str().unwrap();
// let code = v8::String::new(&mut env.scope(), code).unwrap(); let msg = v8::String::new(&mut env.scope(), msg).unwrap();
let error = v8::Exception::error(&mut env.scope(), msg); env.scope().throw_exception(error);
Ok(())}
#[napi_sym::napi_sym]fn napi_throw_range_error( env: *mut Env, _code: *const c_char, msg: *const c_char,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = CStr::from_ptr(code).to_str().unwrap(); let msg = CStr::from_ptr(msg).to_str().unwrap();
// let code = v8::String::new(&mut env.scope(), code).unwrap(); let msg = v8::String::new(&mut env.scope(), msg).unwrap();
let error = v8::Exception::range_error(&mut env.scope(), msg); env.scope().throw_exception(error);
Ok(())}
#[napi_sym::napi_sym]fn napi_throw_type_error( env: *mut Env, _code: *const c_char, msg: *const c_char,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = CStr::from_ptr(code).to_str().unwrap(); let msg = CStr::from_ptr(msg).to_str().unwrap();
// let code = v8::String::new(&mut env.scope(), code).unwrap(); let msg = v8::String::new(&mut env.scope(), msg).unwrap();
let error = v8::Exception::type_error(&mut env.scope(), msg); env.scope().throw_exception(error);
Ok(())}
pub fn get_value_type(value: v8::Local<v8::Value>) -> Option<napi_valuetype> { if value.is_undefined() { Some(napi_undefined) } else if value.is_null() { Some(napi_null) } else if value.is_external() { Some(napi_external) } else if value.is_boolean() { Some(napi_boolean) } else if value.is_number() { Some(napi_number) } else if value.is_big_int() { Some(napi_bigint) } else if value.is_string() { Some(napi_string) } else if value.is_symbol() { Some(napi_symbol) } else if value.is_function() { Some(napi_function) } else if value.is_object() { Some(napi_object) } else { None }}
#[napi_sym::napi_sym]fn napi_typeof( _env: *mut Env, value: napi_value, result: *mut napi_valuetype,) -> Result { if value.is_none() { *result = napi_undefined; return Ok(()); } let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let ty = get_value_type(value); if let Some(ty) = ty { *result = ty; Ok(()) } else { Err(Error::InvalidArg) }}
#[napi_sym::napi_sym]fn napi_unwrap( env: *mut Env, value: napi_value, result: *mut *mut c_void,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); let shared = &*(env.shared as *const EnvShared); let napi_wrap = v8::Local::new(&mut env.scope(), &shared.napi_wrap); let ext = obj.get_private(&mut env.scope(), napi_wrap).unwrap(); let ext = v8::Local::<v8::External>::try_from(ext).unwrap(); *result = ext.value(); Ok(())}
#[napi_sym::napi_sym]fn napi_wrap( env: *mut Env, value: napi_value, native_object: *mut c_void,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?; let value = transmute::<napi_value, v8::Local<v8::Value>>(value); let obj = value.to_object(&mut env.scope()).unwrap(); let shared = &*(env.shared as *const EnvShared); let napi_wrap = v8::Local::new(&mut env.scope(), &shared.napi_wrap); let ext = v8::External::new(&mut env.scope(), native_object); obj.set_private(&mut env.scope(), napi_wrap, ext.into()); Ok(())}
#[napi_sym::napi_sym]fn node_api_throw_syntax_error( env: *mut Env, _code: *const c_char, msg: *const c_char,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = CStr::from_ptr(code).to_str().unwrap(); let msg = CStr::from_ptr(msg).to_str().unwrap();
// let code = v8::String::new(&mut env.scope(), code).unwrap(); let msg = v8::String::new(&mut env.scope(), msg).unwrap();
let error = v8::Exception::syntax_error(&mut env.scope(), msg); env.scope().throw_exception(error);
Ok(())}
#[napi_sym::napi_sym]fn node_api_create_syntax_error( env: *mut Env, _code: napi_value, msg: napi_value, result: *mut napi_value,) -> Result { let env: &mut Env = env.as_mut().ok_or(Error::InvalidArg)?;
// let code = transmute::<napi_value, v8::Local<v8::Value>>(code); let msg = transmute::<napi_value, v8::Local<v8::Value>>(msg);
let msg = msg.to_string(&mut env.scope()).unwrap();
let error = v8::Exception::syntax_error(&mut env.scope(), msg); *result = error.into();
Ok(())}
Version Info