2
2
3
3
#include " env.h"
4
4
#include " memory_tracker-inl.h"
5
+ #include " node_contextify.h"
5
6
#include " node_errors.h"
7
+ #include " node_internals.h"
8
+ #include " node_process.h"
6
9
#include " node_url.h"
7
- #include " util-inl.h"
8
- #include " node_contextify.h"
9
10
#include " node_watchdog.h"
10
- #include " node_process .h"
11
+ #include " util-inl .h"
11
12
12
13
#include < sys/stat.h> // S_IFDIR
13
14
@@ -22,6 +23,8 @@ using node::contextify::ContextifyContext;
22
23
using node::url::URL;
23
24
using node::url::URL_FLAGS_FAILED;
24
25
using v8::Array;
26
+ using v8::ArrayBuffer;
27
+ using v8::ArrayBufferView;
25
28
using v8::Context;
26
29
using v8::EscapableHandleScope;
27
30
using v8::Function;
@@ -46,6 +49,7 @@ using v8::ScriptCompiler;
46
49
using v8::ScriptOrigin;
47
50
using v8::ScriptOrModule;
48
51
using v8::String;
52
+ using v8::UnboundModuleScript;
49
53
using v8::Undefined;
50
54
using v8::Value;
51
55
@@ -133,7 +137,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
133
137
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
134
138
CHECK (args[3 ]->IsFunction ());
135
139
} else {
136
- // new ModuleWrap(url, context, source, lineOffset, columOffset)
140
+ // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData )
137
141
CHECK (args[2 ]->IsString ());
138
142
CHECK (args[3 ]->IsNumber ());
139
143
line_offset = args[3 ].As <Integer>();
@@ -169,6 +173,18 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
169
173
module = Module::CreateSyntheticModule (isolate, url, export_names,
170
174
SyntheticModuleEvaluationStepsCallback);
171
175
} else {
176
+ ScriptCompiler::CachedData* cached_data = nullptr ;
177
+ if (!args[5 ]->IsUndefined ()) {
178
+ CHECK (args[5 ]->IsArrayBufferView ());
179
+ Local<ArrayBufferView> cached_data_buf = args[5 ].As <ArrayBufferView>();
180
+ ArrayBuffer::Contents contents =
181
+ cached_data_buf->Buffer ()->GetContents ();
182
+ uint8_t * data = static_cast <uint8_t *>(contents.Data ());
183
+ cached_data =
184
+ new ScriptCompiler::CachedData (data + cached_data_buf->ByteOffset (),
185
+ cached_data_buf->ByteLength ());
186
+ }
187
+
172
188
Local<String> source_text = args[2 ].As <String>();
173
189
ScriptOrigin origin (url,
174
190
line_offset, // line offset
@@ -180,8 +196,15 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
180
196
False (isolate), // is WASM
181
197
True (isolate), // is ES Module
182
198
host_defined_options);
183
- ScriptCompiler::Source source (source_text, origin);
184
- if (!ScriptCompiler::CompileModule (isolate, &source).ToLocal (&module )) {
199
+ ScriptCompiler::Source source (source_text, origin, cached_data);
200
+ ScriptCompiler::CompileOptions options;
201
+ if (source.GetCachedData () == nullptr ) {
202
+ options = ScriptCompiler::kNoCompileOptions ;
203
+ } else {
204
+ options = ScriptCompiler::kConsumeCodeCache ;
205
+ }
206
+ if (!ScriptCompiler::CompileModule (isolate, &source, options)
207
+ .ToLocal (&module )) {
185
208
if (try_catch.HasCaught () && !try_catch.HasTerminated ()) {
186
209
CHECK (!try_catch.Message ().IsEmpty ());
187
210
CHECK (!try_catch.Exception ().IsEmpty ());
@@ -191,6 +214,13 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
191
214
}
192
215
return ;
193
216
}
217
+ if (options == ScriptCompiler::kConsumeCodeCache &&
218
+ source.GetCachedData ()->rejected ) {
219
+ THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED (
220
+ env, " cachedData buffer was rejected" );
221
+ try_catch.ReThrow ();
222
+ return ;
223
+ }
194
224
}
195
225
}
196
226
@@ -1551,8 +1581,7 @@ MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
1551
1581
return ret;
1552
1582
}
1553
1583
1554
- void ModuleWrap::SetSyntheticExport (
1555
- const v8::FunctionCallbackInfo<v8::Value>& args) {
1584
+ void ModuleWrap::SetSyntheticExport (const FunctionCallbackInfo<Value>& args) {
1556
1585
Isolate* isolate = args.GetIsolate ();
1557
1586
Local<Object> that = args.This ();
1558
1587
@@ -1572,6 +1601,35 @@ void ModuleWrap::SetSyntheticExport(
1572
1601
USE (module ->SetSyntheticModuleExport (isolate, export_name, export_value));
1573
1602
}
1574
1603
1604
+ void ModuleWrap::CreateCachedData (const FunctionCallbackInfo<Value>& args) {
1605
+ Isolate* isolate = args.GetIsolate ();
1606
+ Local<Object> that = args.This ();
1607
+
1608
+ ModuleWrap* obj;
1609
+ ASSIGN_OR_RETURN_UNWRAP (&obj, that);
1610
+
1611
+ CHECK (!obj->synthetic_ );
1612
+
1613
+ Local<Module> module = obj->module_ .Get (isolate);
1614
+
1615
+ CHECK_LT (module ->GetStatus (), v8::Module::Status::kEvaluating );
1616
+
1617
+ Local<UnboundModuleScript> unbound_module_script =
1618
+ module ->GetUnboundModuleScript ();
1619
+ std::unique_ptr<ScriptCompiler::CachedData> cached_data (
1620
+ ScriptCompiler::CreateCodeCache (unbound_module_script));
1621
+ Environment* env = Environment::GetCurrent (args);
1622
+ if (!cached_data) {
1623
+ args.GetReturnValue ().Set (Buffer::New (env, 0 ).ToLocalChecked ());
1624
+ } else {
1625
+ MaybeLocal<Object> buf =
1626
+ Buffer::Copy (env,
1627
+ reinterpret_cast <const char *>(cached_data->data ),
1628
+ cached_data->length );
1629
+ args.GetReturnValue ().Set (buf.ToLocalChecked ());
1630
+ }
1631
+ }
1632
+
1575
1633
void ModuleWrap::Initialize (Local<Object> target,
1576
1634
Local<Value> unused,
1577
1635
Local<Context> context,
@@ -1587,6 +1645,7 @@ void ModuleWrap::Initialize(Local<Object> target,
1587
1645
env->SetProtoMethod (tpl, " instantiate" , Instantiate);
1588
1646
env->SetProtoMethod (tpl, " evaluate" , Evaluate);
1589
1647
env->SetProtoMethod (tpl, " setExport" , SetSyntheticExport);
1648
+ env->SetProtoMethodNoSideEffect (tpl, " createCachedData" , CreateCachedData);
1590
1649
env->SetProtoMethodNoSideEffect (tpl, " getNamespace" , GetNamespace);
1591
1650
env->SetProtoMethodNoSideEffect (tpl, " getStatus" , GetStatus);
1592
1651
env->SetProtoMethodNoSideEffect (tpl, " getError" , GetError);
0 commit comments