Skip to content

Commit

Permalink
Fixed namespace/context error
Browse files Browse the repository at this point in the history
  • Loading branch information
redoC-A2k committed Apr 1, 2024
1 parent d443b34 commit 48c0636
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 41 deletions.
148 changes: 148 additions & 0 deletions JS/jsonnet/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use jrsonnet_stdlib::{builtin_type, Settings};
use std::{cell::{Ref, RefCell, RefMut}, collections::HashMap, rc::Rc};

use jrsonnet_evaluator::{
error::ErrorKind::ImportSyntaxError, function::{builtin, FuncVal, TlaArg}, stdlib, tb, trace::PathResolver, ContextBuilder, ContextInitializer, ObjValue, ObjValueBuilder, Result, State, Thunk, Val
};
use jrsonnet_gcmodule::Trace;
use jrsonnet_parser::{IStr, Source};
use jrsonnet_stdlib::{StdTracePrinter, TracePrinter};

#[builtin]
fn join(a: String, b: String) -> String {
format!("{}{}", a, b)
}

#[builtin]
fn regex_match(a: String, b: String) -> Vec<String> {
// log(&a);
// log(&b);
let re = regex::Regex::new(&b).unwrap();
let mut matches = Vec::new();
for cap in re.captures_iter(&a) {
if cap.len() == 0 {
continue;
}
if cap.len() == 1 {
matches.push(cap[0].to_string());
continue;
}
matches.push(cap[1].to_string());
}
if matches.len() == 0 {
matches.push("".to_string());
}
matches
}

fn arakoolib_uncached() -> ObjValue {
let mut builder = ObjValueBuilder::new();
builder.method("join", join::INST);
builder.method("regexMatch", regex_match::INST);
builder.build()
}

#[derive(Trace, Clone)]
pub struct ArakooContextInitializer {
/// When we don't need to support legacy-this-file, we can reuse same context for all files
#[cfg(not(feature = "legacy-this-file"))]
context: jrsonnet_evaluator::Context,
/// For `populate`
#[cfg(not(feature = "legacy-this-file"))]
stdlib_thunk: Thunk<Val>,
arakoolib_thunk: Thunk<Val>,
settings: Rc<RefCell<jrsonnet_stdlib::Settings>>,
}

fn extvar_source(name: &str, code: impl Into<IStr>) -> Source {
let source_name = format!("<extvar:{name}>");
Source::new_virtual(source_name.into(), code.into())
}

impl ArakooContextInitializer {
pub fn new(_s: State, resolver: PathResolver) -> Self {
let settings = jrsonnet_stdlib::Settings {
ext_vars: Default::default(),
ext_natives: Default::default(),
trace_printer: Box::new(StdTracePrinter::new(resolver.clone())),
path_resolver: resolver,
};
let settings = Rc::new(RefCell::new(settings));
let stdlib_obj = jrsonnet_stdlib::stdlib_uncached(settings.clone());
#[cfg(not(feature = "legacy-this-file"))]
let stdlib_thunk = Thunk::evaluated(Val::Obj(stdlib_obj));
let arakoolib_obj = arakoolib_uncached();
let arakoolib_thunk = Thunk::evaluated(Val::Obj(arakoolib_obj));
Self {
#[cfg(not(feature = "legacy-this-file"))]
context: {
let mut context = ContextBuilder::with_capacity(_s, 1);
context.bind("std", stdlib_thunk.clone());
context.bind("arakoo", arakoolib_thunk.clone());
context.build()
},
#[cfg(not(feature = "legacy-this-file"))]
stdlib_thunk,
arakoolib_thunk,
settings,
}
}
pub fn settings(&self) -> Ref<Settings> {
self.settings.borrow()
}
pub fn settings_mut(&self) -> RefMut<Settings> {
self.settings.borrow_mut()
}
pub fn add_ext_var(&self, name: IStr, value: Val) {
self.settings_mut()
.ext_vars
.insert(name, TlaArg::Val(value));
}
pub fn add_ext_str(&self, name: IStr, value: IStr) {
self.settings_mut()
.ext_vars
.insert(name, TlaArg::String(value));
}
pub fn add_ext_code(&self, name: &str, code: impl Into<IStr>) -> Result<()> {
let code = code.into();
let source = extvar_source(name, code.clone());
let parsed = jrsonnet_parser::parse(
&code,
&jrsonnet_parser::ParserSettings {
source: source.clone(),
},
)
.map_err(|e| ImportSyntaxError {
path: source,
error: Box::new(e),
})?;
// self.data_mut().volatile_files.insert(source_name, code);
self.settings_mut()
.ext_vars
.insert(name.into(), TlaArg::Code(parsed));
Ok(())
}
pub fn add_native(&self, name: impl Into<IStr>, cb: impl Into<FuncVal>) {
self.settings_mut()
.ext_natives
.insert(name.into(), cb.into());
}
}

impl jrsonnet_evaluator::ContextInitializer for ArakooContextInitializer {
fn reserve_vars(&self) -> usize {
1
}
#[cfg(not(feature = "legacy-this-file"))]
fn initialize(&self, _s: State, _source: Source) -> jrsonnet_evaluator::Context {
self.context.clone()
}
#[cfg(not(feature = "legacy-this-file"))]
fn populate(&self, _for_file: Source, builder: &mut ContextBuilder) {
builder.bind("std", self.stdlib_thunk.clone());
builder.bind("arakoo", self.arakoolib_thunk.clone());
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
Binary file modified JS/jsonnet/src/jsonnet_wasm_bg.wasm
Binary file not shown.
64 changes: 23 additions & 41 deletions JS/jsonnet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::Path;

use jrsonnet_evaluator::{
apply_tla,
function::{builtin, TlaArg},
Expand All @@ -10,6 +12,8 @@ use jrsonnet_evaluator::{
use jrsonnet_parser::IStr;
use wasm_bindgen::prelude::*;

mod context;

#[wasm_bindgen(module = "/read-file.js")]
extern "C" {
#[wasm_bindgen(catch)]
Expand All @@ -34,10 +38,11 @@ pub struct VM {
pub fn jsonnet_make() -> *mut VM {
let state = State::default();
state.settings_mut().import_resolver = tb!(FileImportResolver::default());
state.settings_mut().context_initializer = tb!(jrsonnet_stdlib::ContextInitializer::new(
state.clone(),
PathResolver::new_cwd_fallback(),
));
// state.set_context_initializer((jrsonnet_stdlib::ContextInitializer::new(
// state.clone(),
// PathResolver::new_cwd_fallback(),
// ),ArakooContext::ArakooContextInitializer::default()));
state.set_context_initializer(context::ArakooContextInitializer::new(state.clone(), PathResolver::new_cwd_fallback()));
// add_namespace(&state);
Box::into_raw(Box::new(VM {
state,
Expand Down Expand Up @@ -98,58 +103,35 @@ pub fn jsonnet_evaluate_file(vm: *mut VM, filename: &str) -> String {
}
}


#[wasm_bindgen]
pub fn ext_string(vm: *mut VM, key: &str, value: &str) {
let vm = unsafe { &mut *vm };
let any_initializer = vm.state.context_initializer();
any_initializer
// let context_initializer_ref = vm.state.context_initializer();

// Dereference the Ref to access the trait object
let context_initializer = &*vm.state.context_initializer();
println!("{:?}",context_initializer.as_any().type_id());

let context_initializer = vm.state.context_initializer();

println!("Type of context initializer: {:?}", std::any::type_name_of_val(&*context_initializer));

context_initializer
.as_any()
.downcast_ref::<jrsonnet_stdlib::ContextInitializer>()
.downcast_ref::<context::ArakooContextInitializer>()
.expect("only stdlib context initializer supported")
.add_ext_var(key.into(), Val::Str(value.into()));
}

fn add_namespace(state: &State) {
let mut bobj = ObjValueBuilder::new();
bobj.method("join", join::INST);
bobj.method("regexMatch", regex_match::INST);
state.add_global("arakoo".into(), Thunk::evaluated(Val::Obj(bobj.build())))
}

#[builtin]
fn join(a: String, b: String) -> String {
format!("{}{}", a, b)
}

#[builtin]
fn regex_match(a: String, b: String) -> Vec<String> {
log(&a);
log(&b);
let re = regex::Regex::new(&b).unwrap();
let mut matches = Vec::new();
for cap in re.captures_iter(&a) {
if cap.len() == 0 {
continue;
}
if cap.len() == 1 {
matches.push(cap[0].to_string());
continue;
}
matches.push(cap[1].to_string());
}
if matches.len() == 0 {
matches.push("".to_string());
}
matches
}

#[cfg(test)]
mod test {
use super::*;
use regex::Regex;
#[test]
// #[wasm_bindgen]
pub fn test() {
pub fn test_ext_string() {
let vm = jsonnet_make();
// let filename = CString::new("filename").unwrap();
let filename = "filename";
Expand Down

0 comments on commit 48c0636

Please sign in to comment.