runtimejs / runtime

[not maintained] Lightweight JavaScript library operating system for the cloud
http://runtimejs.org
Apache License 2.0
1.93k stars 128 forks source link

Evaluate in different context #152

Open RossComputerGuy opened 7 years ago

RossComputerGuy commented 7 years ago

Recently, I've been messing around with the Runtime.js kernel. I've created a syscall that can allow a script to be evaluated in its own context. Here is the code:

NATIVE_FUNCTION(NativesObject,EvalContext) {
  PROLOGUE_NOTHIS;
  USEARG(0);
  USEARG(1);
  USEARG(2);
  VALIDATEARG(1, STRING, "eval: argument 1 is not a string");

  if(!arg0->IsObject()) THROW_ERROR("argument 0 is not an object");
  v8::Local<v8::Object> globals = arg0.As<v8::Object>();
  v8::Local<v8::ObjectTemplate> global { v8::ObjectTemplate::New(iv8) };
  v8::Local<v8::Context> ctx = v8::Context::New(iv8,nullptr,global);
  v8::Context::Scope cs(ctx);
  ctx->Global()->Set(ctx,v8::String::NewFromUtf8(iv8,"global",v8::NewStringType::kNormal).ToLocalChecked(),globals);

  v8::ScriptOrigin origin((!arg2.IsEmpty() && arg2->IsString()) ? arg2.As<v8::String>() : v8::String::Empty(iv8));

  v8::Local<v8::String> source_code = arg1.As<v8::String>();
  v8::ScriptCompiler::Source source(source_code,origin);
  v8::MaybeLocal<v8::Script> maybe_script = v8::ScriptCompiler::Compile(ctx,&source,v8::ScriptCompiler::CompileOptions::kNoCompileOptions);

  v8::Local<v8::Script> script;
  if(!maybe_script.ToLocal(&script)) return;

  RT_ASSERT(!script.IsEmpty());
  v8::MaybeLocal<v8::Value> maybe_result = script->Run(ctx);
  v8::Local<v8::Value> result;
  if(!maybe_result.ToLocal(&result)) return;

  RT_ASSERT(!result.IsEmpty());
  args.GetReturnValue().Set(result);
}
piranna commented 7 years ago

Pretty interesting, seems it could be the basis for runtime.js Javascript-based processes :-) or at least threads :-P

RossComputerGuy commented 7 years ago

Right now, it doesn't fully work. It returns undefined when I run __SYSCALL.evalContext({ print: (txt) => txt },"print(\"Hi\");")

piranna commented 7 years ago

Does it print?

RossComputerGuy commented 7 years ago

No

iefserge commented 7 years ago

Very cool, I think this would be similar to https://nodejs.org/api/vm.html#vm_vm_runinnewcontext_code_sandbox_options

Unfortunately, contexts can't run in parallel with other contexts in the same isolate (vm instance). They're like an iframes in the browser, have their own global objects, but share the same heap.