From 573f76669f636397ab20302588814d68f6618b5a Mon Sep 17 00:00:00 2001 From: Jeroen Ooms Date: Sat, 5 Oct 2024 19:42:43 +0200 Subject: [PATCH] More wip --- src/bindings.cpp | 68 +++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/src/bindings.cpp b/src/bindings.cpp index 9ec7ac0..32298ec 100644 --- a/src/bindings.cpp +++ b/src/bindings.cpp @@ -47,6 +47,15 @@ void ctx_finalizer(ctx_type* context ){ static v8::Isolate* isolate = NULL; static v8::Platform* platformptr = NULL; +static std::string read_text(std::string filename) { + std::ifstream t(filename); + if(t.fail()) + throw std::runtime_error("Failed to find module file: " + filename); + std::stringstream buffer; + buffer << t.rdbuf(); + return buffer.str(); +} + // Extracts a C string from a V8 Utf8Value. static const char* ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; @@ -66,18 +75,14 @@ static void fatal_cb(const char* location, const char* message){ REprintf("V8 FATAL ERROR in %s: %s", location, message); } -static v8::Local compile_module(std::string src, v8::Local context); +static v8::Local read_module(std::string filename, v8::Local context); static v8::MaybeLocal ResolveModuleCallback(v8::Local context, v8::Local specifier, v8::Local import_attributes, v8::Local referrer) { v8::String::Utf8Value name(context->GetIsolate(), specifier); - Rcpp::Function r_readlines = Rcpp::Environment::namespace_env("V8")["read_file_string"]; - Rcpp::CharacterVector out = r_readlines(Rcpp::String(*name)); - if(out.inherits("cb_error")) - throw std::runtime_error(std::string(out.at(0))); - return compile_module(std::string(out.at(0)).c_str(), context); + return read_module(*name, context); } static v8::MaybeLocal ResolveDynamicModuleCallback( @@ -89,45 +94,32 @@ static v8::MaybeLocal ResolveDynamicModuleCallback( v8::Local resolver = v8::Promise::Resolver::New(context).ToLocalChecked(); v8::MaybeLocal promise(resolver->GetPromise()); v8::String::Utf8Value name(context->GetIsolate(), specifier); - Rcpp::Function r_readlines = Rcpp::Environment::namespace_env("V8")["read_file_string"]; - Rcpp::CharacterVector out = r_readlines(Rcpp::String(*name)); - v8::Local source_text(ToJSString(std::string(out.at(0)).c_str())); - if(out.inherits("cb_error")){ - resolver->Reject(context, source_text).FromMaybe(false); //R error reading file - return promise; - } - if(source_text.IsEmpty()){ - resolver->Reject(context, ToJSString("Failed to read Module source code.")).FromMaybe(false); - return promise; - } - v8::ScriptOrigin origin(specifier, 0, 0, false, -1, v8::Local(), false, false, true); - v8::ScriptCompiler::Source source(source_text, origin); - v8::Local module; - if (!v8::ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)){ - resolver->Reject(context, ToJSString("Failure at CompileModule")).FromMaybe(false); - return promise; - } - if(!module->InstantiateModule(context, ResolveModuleCallback).FromMaybe(false)){ - resolver->Reject(context, ToJSString("Failure at InstantiateModule")).FromMaybe(false); - return promise; - } - v8::Local retValue; - if (!module->Evaluate(context).ToLocal(&retValue)) { - resolver->Reject(context, ToJSString("Failure evaluating")).FromMaybe(false); - return promise; + try { + v8::Local module = read_module(*name, context); + v8::Local retValue; + if (!module->Evaluate(context).ToLocal(&retValue)) + throw std::runtime_error("Failure loading module"); + resolver->Resolve(context, module->GetModuleNamespace()).FromMaybe(false); + } catch(std::runtime_error err) { + resolver->Reject(context, ToJSString(err.what())).FromMaybe(false); + } catch(...) { + resolver->Reject(context, ToJSString("Unknown failure loading dynamic module")).FromMaybe(false); } - resolver->Resolve(context, module->GetModuleNamespace()).FromMaybe(false); return promise; } - /* Helper fun that compiles JavaScript source code */ -static v8::Local compile_module(std::string src, v8::Local context){ - v8::Local source_text = ToJSString(src.c_str()); +static v8::Local read_module(std::string filename, v8::Local context){ + v8::Local source_text = ToJSString(read_text(filename).c_str()); if(source_text.IsEmpty()) throw std::runtime_error("Failed to load JavaScript source. Check memory/stack limits."); - v8::ScriptOrigin origin(ToJSString( "main.mjs"), 0, 0, false, -1, - v8::Local(), false, false, true); +#if V8_VERSION_TOTAL < 1201 + v8::ScriptOrigin origin(isolate, +#else + v8::ScriptOrigin origin( +#endif + ToJSString( filename.c_str()), 0, 0, false, -1, + v8::Local(), false, false, true); v8::ScriptCompiler::Source source(source_text, origin); v8::Local module; if (!v8::ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module))