-
-
Notifications
You must be signed in to change notification settings - Fork 44
Expand file tree
/
Copy pathjsb_amd_module_loader.cpp
More file actions
123 lines (107 loc) · 4.19 KB
/
jsb_amd_module_loader.cpp
File metadata and controls
123 lines (107 loc) · 4.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "jsb_amd_module_loader.h"
#include "jsb_builtins.h"
#include "jsb_environment.h"
namespace jsb
{
bool AMDModuleLoader::load(Environment* p_env, JavaScriptModule& p_module)
{
typedef v8::Local<v8::Value> LocalValue;
v8::Isolate* isolate = p_env->get_isolate();
const int len = (int) deps_.size();
bool succeeded = true;
LocalValue* dep_vals = jsb_stackalloc(LocalValue, len);
const String self_module_id = p_module.id;
// setup self exports
const v8::Local<v8::Object> self_exports = v8::Object::New(isolate);
p_module.exports.Reset(isolate, self_exports);
// prepare all dependencies
int index = 0;
for (; index < len; ++index)
{
const String& dep_module_id = deps_[index];
memnew_placement(&dep_vals[index], LocalValue);
// special case: `require` & `exports`
if (dep_module_id == "require")
{
dep_vals[index] = p_env->_new_require_func(self_module_id, !internal_);
continue;
}
if (dep_module_id == "exports")
{
dep_vals[index] = self_exports;
continue;
}
if (const JavaScriptModule* module = p_env->_load_module(self_module_id, dep_module_id))
{
JSB_LOG(Verbose, "load dep: %s", dep_module_id);
dep_vals[index] = module->exports.Get(isolate);
continue;
}
succeeded = false;
break;
}
if (succeeded)
{
const v8::Local<v8::Context> context = isolate->GetCurrentContext();
const v8::Local<v8::Function> evaluator = evaluator_.Get(isolate);
v8::Local<v8::Value> result;
if (evaluator->Call(context, v8::Undefined(isolate), len, dep_vals).ToLocal(&result))
{
if (!result->IsUndefined())
{
p_module.exports.Reset(isolate, result);
}
}
else
{
JSB_LOG(Error, "failed to evaluate AMD module");
succeeded = false;
}
}
for (--index; index >= 0; --index)
{
dep_vals[index].~LocalValue();
}
return succeeded;
}
Error AMDModuleLoader::load_source(Environment* p_env, const internal::PresetSource& p_source)
{
size_t len;
const char* str = p_source.get_data(len);
if (!str) return ERR_FILE_NOT_FOUND;
jsb_check(len == (size_t) (int) len);
load_source(p_env, str, (int) len, p_source.get_filename(), true);
return OK;
}
void AMDModuleLoader::load_source(Environment* p_env, const char* p_source, int p_len, const String& p_name, bool p_internal)
{
jsb_check(strstr(p_source, "(function(define){") == p_source);
v8::Isolate* isolate = p_env->get_isolate();
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
v8::Local<v8::Context> context = p_env->get_context();
v8::Context::Scope context_scope(context);
impl::TryCatch try_catch(isolate);
const v8::MaybeLocal<v8::Value> func_maybe = impl::Helper::compile_function(context, p_source, p_len, p_name);
if (try_catch.has_caught())
{
JSB_LOG(Error, "%s", BridgeHelper::get_exception(try_catch));
return;
}
v8::Local<v8::Value> func;
if (!func_maybe.ToLocal(&func) || !func->IsFunction())
{
JSB_LOG(Error, "something wrong on evaluating AMD source %s", p_name);
return;
}
v8::Local<v8::Boolean> internal = v8::Boolean::New(isolate, p_internal);
v8::Local<v8::Value> argv[] = {JSB_NEW_FUNCTION(context, Builtins::_define, internal)};
const v8::MaybeLocal<v8::Value> result = func.As<v8::Function>()->Call(context, v8::Undefined(isolate), ::std::size(argv), argv);
if (try_catch.has_caught())
{
JSB_LOG(Error, "%s", BridgeHelper::get_exception(try_catch));
return;
}
jsb_unused(result);
}
} // namespace jsb