Skip to content

Commit

Permalink
More wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroen committed Oct 5, 2024
1 parent 18c4081 commit 573f766
Showing 1 changed file with 30 additions and 38 deletions.
68 changes: 30 additions & 38 deletions src/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 : "<string conversion failed>";
Expand All @@ -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<v8::Module> compile_module(std::string src, v8::Local<v8::Context> context);
static v8::Local<v8::Module> read_module(std::string filename, v8::Local<v8::Context> context);

static v8::MaybeLocal<v8::Module> ResolveModuleCallback(v8::Local<v8::Context> context,
v8::Local<v8::String> specifier,
v8::Local<v8::FixedArray> import_attributes,
v8::Local<v8::Module> 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<v8::Promise> ResolveDynamicModuleCallback(
Expand All @@ -89,45 +94,32 @@ static v8::MaybeLocal<v8::Promise> ResolveDynamicModuleCallback(
v8::Local<v8::Promise::Resolver> resolver = v8::Promise::Resolver::New(context).ToLocalChecked();
v8::MaybeLocal<v8::Promise> 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<v8::String> 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<v8::Value>(), false, false, true);
v8::ScriptCompiler::Source source(source_text, origin);
v8::Local<v8::Module> 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<v8::Value> retValue;
if (!module->Evaluate(context).ToLocal(&retValue)) {
resolver->Reject(context, ToJSString("Failure evaluating")).FromMaybe(false);
return promise;
try {
v8::Local<v8::Module> module = read_module(*name, context);
v8::Local<v8::Value> 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<v8::Module> compile_module(std::string src, v8::Local<v8::Context> context){
v8::Local<v8::String> source_text = ToJSString(src.c_str());
static v8::Local<v8::Module> read_module(std::string filename, v8::Local<v8::Context> context){
v8::Local<v8::String> 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<v8::Value>(), 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<v8::Value>(), false, false, true);
v8::ScriptCompiler::Source source(source_text, origin);
v8::Local<v8::Module> module;
if (!v8::ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module))
Expand Down

0 comments on commit 573f766

Please sign in to comment.