Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20231002 uncurry and typescript fixed #47

Merged
merged 3 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 37 additions & 31 deletions wasm/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ use wasm_bindgen::JsCast;

use clvmr::allocator::Allocator;

use clvm_tools_rs::classic::clvm::__type_compatibility__::{Bytes, Stream, UnvalidatedBytesFromType};
use crate::jsval::{
btreemap_to_object, get_property, js_object_from_sexp, js_pair, object_to_value,
read_string_to_string_map, sexp_from_js_object,
};
use crate::objects::Program;
use clvm_tools_rs::classic::clvm::__type_compatibility__::{
Bytes, Stream, UnvalidatedBytesFromType,
};
use clvm_tools_rs::classic::clvm::serialize::sexp_to_stream;
use clvm_tools_rs::classic::clvm_tools::clvmc::compile_clvm_inner;
use clvm_tools_rs::classic::clvm_tools::stages::stage_0::DefaultProgramRunner;
Expand All @@ -30,11 +37,6 @@ use clvm_tools_rs::compiler::repl::Repl;
use clvm_tools_rs::compiler::runtypes::RunFailure;
use clvm_tools_rs::compiler::sexp::SExp;
use clvm_tools_rs::compiler::srcloc::Srcloc;
use crate::jsval::{
btreemap_to_object, get_property, js_object_from_sexp, js_pair, object_to_value,
read_string_to_string_map, sexp_from_js_object,
};
use crate::objects::Program;

#[cfg(feature = "wee_alloc")]
#[global_allocator]
Expand Down Expand Up @@ -117,20 +119,14 @@ pub fn create_clvm_runner_err(error: String) -> JsValue {

fn create_clvm_runner_run_failure(err: &RunFailure) -> JsValue {
match err {
RunFailure::RunErr(l, e) => {
create_clvm_runner_err(format!("{}: Error {}", l, e))
}
RunFailure::RunExn(l, e) => {
create_clvm_runner_err(format!("{}: Exn {}", l, e))
}
RunFailure::RunErr(l, e) => create_clvm_runner_err(format!("{}: Error {}", l, e)),
RunFailure::RunExn(l, e) => create_clvm_runner_err(format!("{}: Exn {}", l, e)),
}
}

fn create_clvm_compile_failure(err: &CompileErr) -> JsValue {
match err {
CompileErr(l, e) => {
create_clvm_runner_err(format!("{}: Error {}", l, e))
}
CompileErr(l, e) => create_clvm_runner_err(format!("{}: Error {}", l, e)),
}
}

Expand All @@ -144,7 +140,12 @@ impl CldbSingleBespokeOverride for JsBespokeOverride {
// When the user returns, try to convert the result back to sexp.
fn get_override(&self, env: Rc<SExp>) -> Result<Rc<SExp>, RunFailure> {
let args = js_sys::Array::new();
args.set(0, js_object_from_sexp(env.clone()).map_err(|_| RunFailure::RunErr(env.loc(), "error converting override value".to_string()))?);
args.set(
0,
js_object_from_sexp(env.clone()).map_err(|_| {
RunFailure::RunErr(env.loc(), "error converting override value".to_string())
})?,
);
self.fun
.apply(&JsValue::null(), &args)
.map_err(|e| {
Expand Down Expand Up @@ -247,7 +248,9 @@ pub fn create_clvm_runner(
#[wasm_bindgen]
pub fn final_value(runner: i32) -> JsValue {
with_runner(runner, |r| {
r.cldbrun.final_result().map(|v| js_object_from_sexp(v).unwrap_or_else(|e| e))
r.cldbrun
.final_result()
.map(|v| js_object_from_sexp(v).unwrap_or_else(|e| e))
})
.unwrap_or_else(JsValue::null)
}
Expand Down Expand Up @@ -280,7 +283,10 @@ fn make_compile_output(result_stream: &Stream, symbol_table: &HashMap<String, St
);
let symbol_array = js_sys::Array::new();
for (idx, (k, v)) in symbol_table.iter().enumerate() {
symbol_array.set(idx as u32, js_pair(JsValue::from_str(k), JsValue::from_str(v)));
symbol_array.set(
idx as u32,
js_pair(JsValue::from_str(k), JsValue::from_str(v)),
);
}
let symbol_object = object_to_value(&js_sys::Object::from_entries(&symbol_array).unwrap());
array.set(1, js_pair(JsValue::from_str("symbols"), symbol_object));
Expand All @@ -303,8 +309,7 @@ pub fn compile(input_js: JsValue, filename_js: JsValue, search_paths_js: Vec<JsV
.map(|j| j.as_string().unwrap())
.collect();

let opts = Rc::new(DefaultCompilerOpts::new(&filename))
.set_search_paths(&search_paths);
let opts = Rc::new(DefaultCompilerOpts::new(&filename)).set_search_paths(&search_paths);
match compile_clvm_inner(
&mut allocator,
opts,
Expand Down Expand Up @@ -370,15 +375,13 @@ pub fn compose_run_function(
));
}
};
let hash_bytes = match Bytes::new_validated(Some(UnvalidatedBytesFromType::Hex(function_hash.clone()))) {
Err(e) => {
return create_clvm_compile_failure(&CompileErr(
program.loc(),
e.to_string(),
));
},
Ok(x) => x,
};
let hash_bytes =
match Bytes::new_validated(Some(UnvalidatedBytesFromType::Hex(function_hash.clone()))) {
Err(e) => {
return create_clvm_compile_failure(&CompileErr(program.loc(), e.to_string()));
}
Ok(x) => x,
};

let function_path = match path_to_function(main_env.1.clone(), &hash_bytes.data().clone()) {
Some(p) => p,
Expand Down Expand Up @@ -489,11 +492,14 @@ pub fn sexp_to_string(v: &JsValue) -> JsValue {

#[wasm_bindgen]
pub fn h(v: String) -> Result<Vec<u8>, JsValue> {
let hex_data = Bytes::new_validated(Some(UnvalidatedBytesFromType::Hex(v))).map_err(|_| js_sys::JsString::from("bad hex input"))?;
let hex_data = Bytes::new_validated(Some(UnvalidatedBytesFromType::Hex(v)))
.map_err(|_| js_sys::JsString::from("bad hex input"))?;
Ok(hex_data.data().clone())
}

#[wasm_bindgen]
pub fn t(a: &JsValue, b: &JsValue) -> Result<JsValue, JsValue> {
Program::as_pair_internal(&Program::cons_internal(&Program::to(a)?, &Program::to(b)?)?)
Program::as_pair_internal(
&Program::cons_internal(&Program::to_internal(a)?, &Program::to_internal(b)?)?.into(),
)
}
95 changes: 51 additions & 44 deletions wasm/src/jsval.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use js_sys;
use js_sys::JSON::stringify;
use js_sys::{Array, BigInt, Object, Reflect};
use wasm_bindgen::JsCast;
Expand Down Expand Up @@ -42,21 +41,27 @@ pub fn js_object_from_sexp(v: Rc<SExp>) -> Result<JsValue, JsValue> {
match v.borrow() {
SExp::Nil(_) => Ok(JsValue::null()),
SExp::Integer(_, i) => Ok(JsValue::bigint_from_str(&i.to_string())),
SExp::QuotedString(_, _, q) => {
Ok(JsValue::from_str(&Bytes::new(Some(BytesFromType::Raw(q.clone()))).decode()))
}
SExp::Atom(_, q) => {
Ok(JsValue::from_str(&Bytes::new(Some(BytesFromType::Raw(q.clone()))).decode()))
}
SExp::QuotedString(_, _, q) => Ok(JsValue::from_str(
&Bytes::new(Some(BytesFromType::Raw(q.clone()))).decode(),
)),
SExp::Atom(_, q) => Ok(JsValue::from_str(
&Bytes::new(Some(BytesFromType::Raw(q.clone()))).decode(),
)),
SExp::Cons(_, a, b) => {
if let Some(lst) = v.proper_list() {
let array = Array::new();
for i in 0..lst.len() {
array.set(i as u32, js_object_from_sexp(Rc::new(lst[i].clone())).unwrap_or_else(|e| e));
for (i, _) in lst.iter().enumerate() {
array.set(
i as u32,
js_object_from_sexp(Rc::new(lst[i].clone())).unwrap_or_else(|e| e),
);
}
Ok(array_to_value(array))
} else {
t(&js_object_from_sexp(a.clone())?, &js_object_from_sexp(b.clone())?)
t(
&js_object_from_sexp(a.clone())?,
&js_object_from_sexp(b.clone())?,
)
}
}
}
Expand Down Expand Up @@ -103,33 +108,37 @@ fn location(o: &Object) -> Option<Srcloc> {
line: l,
col: c,
until: get_property(o, "until")
.and_then(|lo| Object::try_from(&lo).map(|o| o.clone()))
.and_then(|lo| Object::try_from(&lo).cloned())
.and_then(|lo| location_lc_pair(&lo))
.map(|(ll, lc)| Until { line: ll, col: lc }),
})
}

pub fn detect_serializable(loc: &Srcloc, v: &JsValue) -> Option<Rc<SExp>> {
let serialize_key = JsValue::from_str("serialize");
js_sys::Reflect::get(v, &serialize_key).ok().and_then(|serialize| {
Reflect::apply(serialize.unchecked_ref(), v, &js_sys::Array::new()).ok().and_then(|array| {
Array::try_from(array).ok().and_then(|array| {
let mut bytes_array: Vec<u8> = vec![];
for item in array.iter() {
if let Some(n) = item.as_f64() {
if n < 0.0 || n > 255.0 {
return None;
js_sys::Reflect::get(v, &serialize_key)
.ok()
.and_then(|serialize| {
Reflect::apply(serialize.unchecked_ref(), v, &js_sys::Array::new())
.ok()
.and_then(|array| {
Array::try_from(array).ok().and_then(|array| {
let mut bytes_array: Vec<u8> = vec![];
for item in array.iter() {
if let Some(n) = item.as_f64() {
if !(0.0..=255.0).contains(&n) {
return None;
}
bytes_array.push(n as u8);
} else {
return None;
}
}
bytes_array.push(n as u8);
} else {
return None;
}
}

return Some(Rc::new(SExp::QuotedString(loc.clone(), b'x', bytes_array)));
})
Some(Rc::new(SExp::QuotedString(loc.clone(), b'x', bytes_array)))
})
})
})
})
}

pub fn detect_convertible(v: &JsValue) -> Result<Rc<SExp>, JsValue> {
Expand All @@ -146,9 +155,9 @@ pub fn detect_convertible(v: &JsValue) -> Result<Rc<SExp>, JsValue> {
pub fn sexp_from_js_object(sstart: Srcloc, v: &JsValue) -> Option<Rc<SExp>> {
// Already converted value.
if let Ok(res) = js_cache_value_from_js(v) {
find_cached_sexp(res.entry, &res.content).map(|result| {
result.modern.clone()
}).ok()
find_cached_sexp(res.entry, &res.content)
.map(|result| result.modern.clone())
.ok()
} else if v.is_bigint() {
BigInt::new(v)
.ok()
Expand All @@ -157,30 +166,28 @@ pub fn sexp_from_js_object(sstart: Srcloc, v: &JsValue) -> Option<Rc<SExp>> {
.and_then(|v| v.parse::<Number>().ok())
.map(|x| Rc::new(SExp::Integer(sstart.clone(), x)))
} else if let Some(fval) = v.as_f64() {
(fval as i64).to_bigint()
(fval as i64)
.to_bigint()
.map(|x| Rc::new(SExp::Integer(sstart.clone(), x)))
} else if let Some(g1_bytes) = detect_serializable(&sstart, v) {
Some(g1_bytes)
} else if let Some(converted) = detect_convertible(v).ok() {
} else if let Ok(converted) = detect_convertible(v) {
Some(converted)
} else if Array::is_array(v) {
let a = Array::from(v);
let mut result_value = Rc::new(SExp::Nil(Srcloc::start(&"*js*".to_string())));
let mut result_value = Rc::new(SExp::Nil(Srcloc::start("*js*")));
for i_rev in 0..a.length() {
let i = a.length() - i_rev - 1;
match sexp_from_js_object(sstart.clone(), &a.get(i)) {
Some(nv) => {
result_value = Rc::new(SExp::Cons(nv.loc(), nv, result_value));
}
_ => {}
if let Some(nv) = sexp_from_js_object(sstart.clone(), &a.get(i)) {
result_value = Rc::new(SExp::Cons(nv.loc(), nv, result_value));
}
}
Some(result_value)
} else {
Object::try_from(v)
.map(|o| {
let loc = get_property(o, "location")
.and_then(|o| Object::try_from(&o).map(|o| o.clone()))
.and_then(|o| Object::try_from(&o).cloned())
.and_then(|o| location(&o))
.unwrap_or_else(|| sstart.clone());
get_property(o, "pair")
Expand Down Expand Up @@ -211,21 +218,21 @@ pub fn btreemap_to_object<'a>(iter: impl Iterator<Item = (&'a String, &'a String
let entries = Array::new();
for pv in iter {
let pair = Array::new();
pair.set(0, JsValue::from_str(&pv.0));
pair.set(1, JsValue::from_str(&pv.1));
pair.set(0, JsValue::from_str(pv.0));
pair.set(1, JsValue::from_str(pv.1));
let pair_ref: &JsValue = pair.as_ref();
entries.set(entries.length(), pair_ref.clone());
}
object_to_value(&Object::from_entries(&entries).as_ref().unwrap())
object_to_value(Object::from_entries(&entries).as_ref().unwrap())
}

pub fn read_string_to_string_map(
symbols: &js_sys::Object,
) -> Result<HashMap<String, String>, String> {
let mut result = HashMap::new();
for ent in js_sys::Object::keys(&symbols).values() {
for ent in js_sys::Object::keys(symbols).values() {
let key = ent.unwrap().as_string().unwrap();
match get_property(&symbols, &key).unwrap().as_string() {
match get_property(symbols, &key).unwrap().as_string() {
Some(val) => {
result.insert(key, val);
}
Expand Down
Loading
Loading