Permalink
Browse files

vm, feat: support Sandbox::registerExt, and enable it in rootModule's…

… Sandbox. (#450)
  • Loading branch information...
richardo2016 authored and xicilion committed Aug 12, 2018
1 parent 8aef38e commit faf81989352261de87bbf9fee8e65448aab4f8cf
View
@@ -32,6 +32,7 @@ class SandBox : public SandBox_base {
virtual result_t run(exlib::string fname, v8::Local<v8::Array> argv);
virtual result_t resolve(exlib::string id, exlib::string base, exlib::string& retVal);
virtual result_t require(exlib::string id, exlib::string base, v8::Local<v8::Value>& retVal);
virtual result_t setModuleLoader(exlib::string extname, v8::Local<v8::Function> once_require_func);
virtual result_t get_global(v8::Local<v8::Object>& retVal);
public:
@@ -137,6 +138,24 @@ class SandBox : public SandBox_base {
exlib::string m_ext;
};
static exlib::string _get_extloader_pname(exlib::string extname)
{
return "extloader_p_" + extname;
}
class CustomExtLoader : public SandBox::ExtLoader {
public:
CustomExtLoader(exlib::string t_extname)
: ExtLoader(t_extname.c_str())
{
}
public:
virtual result_t run(SandBox::Context* ctx, Buffer_base* src,
exlib::string name, exlib::string arg_names,
v8::Local<v8::Value>* args, int32_t args_count);
};
public:
virtual result_t custom_resolveId(exlib::string& id, v8::Local<v8::Value>& retVal);
@@ -173,6 +192,16 @@ class SandBox : public SandBox_base {
result_t run_worker(exlib::string fname, Worker_base* worker);
result_t get_loader(exlib::string fname, obj_ptr<ExtLoader>& retVal)
{
find_loader(fname, retVal);
if (!retVal)
retVal = m_loaders[0];
return 0;
}
result_t find_loader(exlib::string fname, obj_ptr<ExtLoader>& retVal)
{
size_t cnt = m_loaders.size();
@@ -186,7 +215,6 @@ class SandBox : public SandBox_base {
}
}
retVal = m_loaders[0];
return 0;
}
@@ -36,6 +36,7 @@ class SandBox_base : public object_base {
virtual result_t run(exlib::string fname, v8::Local<v8::Array> argv) = 0;
virtual result_t resolve(exlib::string id, exlib::string base, exlib::string& retVal) = 0;
virtual result_t require(exlib::string id, exlib::string base, v8::Local<v8::Value>& retVal) = 0;
virtual result_t setModuleLoader(exlib::string extname, v8::Local<v8::Function> once_require_func) = 0;
virtual result_t get_global(v8::Local<v8::Object>& retVal) = 0;
public:
@@ -52,6 +53,7 @@ class SandBox_base : public object_base {
static void s_run(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_resolve(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_require(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_setModuleLoader(const v8::FunctionCallbackInfo<v8::Value>& args);
static void s_get_global(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args);
};
}
@@ -69,7 +71,8 @@ inline ClassInfo& SandBox_base::class_info()
{ "clone", s_clone, false },
{ "run", s_run, false },
{ "resolve", s_resolve, false },
{ "require", s_require, false }
{ "require", s_require, false },
{ "setModuleLoader", s_setModuleLoader, false }
};
static ClassData::ClassProperty s_property[] = {
@@ -270,6 +273,22 @@ inline void SandBox_base::s_require(const v8::FunctionCallbackInfo<v8::Value>& a
METHOD_RETURN();
}
inline void SandBox_base::s_setModuleLoader(const v8::FunctionCallbackInfo<v8::Value>& args)
{
METHOD_NAME("SandBox.setModuleLoader");
METHOD_INSTANCE(SandBox_base);
METHOD_ENTER();
METHOD_OVER(2, 2);
ARG(exlib::string, 0);
ARG(v8::Local<v8::Function>, 1);
hr = pInst->setModuleLoader(v0, v1);
METHOD_VOID();
}
inline void SandBox_base::s_get_global(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Value>& args)
{
v8::Local<v8::Object> vr;
@@ -20,7 +20,6 @@ namespace fibjs {
result_t SandBox::loadFile(exlib::string fname, obj_ptr<Buffer_base>& data)
{
result_t hr;
Isolate* isolate = holder();
Variant var;
hr = fs_base::cc_readFile(fname, "", var);
@@ -174,6 +173,37 @@ result_t SandBox::resolveFile(exlib::string& fname, obj_ptr<Buffer_base>& data,
return CALL_E_FILE_NOT_FOUND;
}
static const char* predefine_exts[] = {
".js",
".jsc",
".json",
".wasm"
};
result_t SandBox::setModuleLoader(exlib::string extname, v8::Local<v8::Function> once_require_func)
{
if (extname.empty())
return CALL_E_INVALIDARG;
if (extname[0] != '.')
return CALL_E_INVALIDARG;
for (int i = 0; i < ARRAYSIZE(predefine_exts); i++)
if (extname == predefine_exts[i])
return CHECK_ERROR(Runtime::setError("SandBox: '" + extname + "' is reserved extension name!"));
obj_ptr<ExtLoader> loader;
find_loader("test" + extname, loader);
if (!loader) {
loader = new CustomExtLoader(extname);
m_loaders.push_back(loader);
}
SetPrivate(SandBox::_get_extloader_pname(extname), once_require_func);
return 0;
}
result_t SandBox::custom_resolveId(exlib::string& id, v8::Local<v8::Value>& retVal)
{
Isolate* isolate = holder();
@@ -311,4 +341,4 @@ result_t SandBox::resolve(exlib::string id, exlib::string base, exlib::string& r
retVal = id;
return 0;
}
}
}
@@ -0,0 +1,57 @@
/**
* @author Richard
* @email richardo2016@mail.com
* @create date 2018-08-11 04:35:51
* @modify date 2018-08-11 04:35:51
* @desc CustomExtLoader for add loader to Sandbox dynamiclly.
*/
#include "Buffer.h"
#include "SandBox.h"
#include "ifs/util.h"
#include "loaders.h"
#include "object.h"
#include "path.h"
namespace fibjs {
result_t SandBox::CustomExtLoader::run(SandBox::Context* ctx, Buffer_base* src,
exlib::string name, exlib::string arg_names,
v8::Local<v8::Value>* args,
int32_t args_count)
{
Isolate* isolate = ctx->m_sb->holder();
v8::Local<v8::String> soname = isolate->NewString(name);
exlib::string pname;
path_base::dirname(name, pname);
v8::Local<v8::Value> require_fn = ctx->m_sb->GetPrivate(SandBox::_get_extloader_pname(m_ext));
// transpile with customFile first :start
std::vector<v8::Local<v8::Value>> transpileArgs;
transpileArgs.resize(1);
src->valueOf(transpileArgs[0]);
TryCatch try_catch;
v8::Local<v8::Value> fileContent = v8::Local<v8::Function>::Cast(require_fn)
->Call(v8::Undefined(isolate->m_isolate),
(int32_t)transpileArgs.size(), transpileArgs.data());
if (try_catch.HasCaught()) {
v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
isolate->m_isolate, 1, v8::StackTrace::kScriptId);
if (stackTrace->GetFrameCount() > 0) {
try_catch.ReThrow();
return CALL_E_JAVASCRIPT;
} else
return CHECK_ERROR(Runtime::setError(GetException(try_catch, 0)));
}
// transpile with customFile first :end
v8::Local<v8::Object> module = v8::Local<v8::Object>::Cast(args[5]);
module->Set(isolate->NewString("exports"), fileContent);
return 0;
};
} // namespace fibjs
View
@@ -92,6 +92,12 @@ interface SandBox : object
*/
Value require(String id, String base);
/*! @brief 对指定的 extname 添加特定的 resolve 方法
@param extname 指定的 extname, 必须以 '.' 开头, 且为非系统内置扩展名
@param once_require_func 一次性引入函数, 所有带 extname 的文件仅会 require 一次
*/
setModuleLoader(String extname, Function once_require_func);
/*! @brief 查询沙箱的 global 对象 */
readonly Object global;
};
Oops, something went wrong.

0 comments on commit faf8198

Please sign in to comment.