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,7 @@ 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::ArrayBufferView;
25
27
using v8::Context;
26
28
using v8::Function;
27
29
using v8::FunctionCallbackInfo;
@@ -44,6 +46,7 @@ using v8::Promise;
44
46
using v8::ScriptCompiler;
45
47
using v8::ScriptOrigin;
46
48
using v8::String;
49
+ using v8::UnboundModuleScript;
47
50
using v8::Undefined;
48
51
using v8::Value;
49
52
@@ -131,7 +134,7 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
131
134
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
132
135
CHECK (args[3 ]->IsFunction ());
133
136
} else {
134
- // new ModuleWrap(url, context, source, lineOffset, columOffset)
137
+ // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData )
135
138
CHECK (args[2 ]->IsString ());
136
139
CHECK (args[3 ]->IsNumber ());
137
140
line_offset = args[3 ].As <Integer>();
@@ -167,6 +170,17 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
167
170
module = Module::CreateSyntheticModule (isolate, url, export_names,
168
171
SyntheticModuleEvaluationStepsCallback);
169
172
} else {
173
+ ScriptCompiler::CachedData* cached_data = nullptr ;
174
+ if (!args[5 ]->IsUndefined ()) {
175
+ CHECK (args[5 ]->IsArrayBufferView ());
176
+ Local<ArrayBufferView> cached_data_buf = args[5 ].As <ArrayBufferView>();
177
+ uint8_t * data = static_cast <uint8_t *>(
178
+ cached_data_buf->Buffer ()->GetBackingStore ()->Data ());
179
+ cached_data =
180
+ new ScriptCompiler::CachedData (data + cached_data_buf->ByteOffset (),
181
+ cached_data_buf->ByteLength ());
182
+ }
183
+
170
184
Local<String> source_text = args[2 ].As <String>();
171
185
ScriptOrigin origin (url,
172
186
line_offset, // line offset
@@ -178,8 +192,15 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
178
192
False (isolate), // is WASM
179
193
True (isolate), // is ES Module
180
194
host_defined_options);
181
- ScriptCompiler::Source source (source_text, origin);
182
- if (!ScriptCompiler::CompileModule (isolate, &source).ToLocal (&module)) {
195
+ ScriptCompiler::Source source (source_text, origin, cached_data);
196
+ ScriptCompiler::CompileOptions options;
197
+ if (source.GetCachedData () == nullptr ) {
198
+ options = ScriptCompiler::kNoCompileOptions ;
199
+ } else {
200
+ options = ScriptCompiler::kConsumeCodeCache ;
201
+ }
202
+ if (!ScriptCompiler::CompileModule (isolate, &source, options)
203
+ .ToLocal (&module)) {
183
204
if (try_catch.HasCaught () && !try_catch.HasTerminated ()) {
184
205
CHECK (!try_catch.Message ().IsEmpty ());
185
206
CHECK (!try_catch.Exception ().IsEmpty ());
@@ -189,6 +210,13 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
189
210
}
190
211
return ;
191
212
}
213
+ if (options == ScriptCompiler::kConsumeCodeCache &&
214
+ source.GetCachedData ()->rejected ) {
215
+ THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED (
216
+ env, " cachedData buffer was rejected" );
217
+ try_catch.ReThrow ();
218
+ return ;
219
+ }
192
220
}
193
221
}
194
222
@@ -1507,8 +1535,7 @@ MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
1507
1535
return ret;
1508
1536
}
1509
1537
1510
- void ModuleWrap::SetSyntheticExport (
1511
- const v8::FunctionCallbackInfo<v8::Value>& args) {
1538
+ void ModuleWrap::SetSyntheticExport (const FunctionCallbackInfo<Value>& args) {
1512
1539
Isolate* isolate = args.GetIsolate ();
1513
1540
Local<Object> that = args.This ();
1514
1541
@@ -1528,6 +1555,35 @@ void ModuleWrap::SetSyntheticExport(
1528
1555
USE (module->SetSyntheticModuleExport (isolate, export_name, export_value));
1529
1556
}
1530
1557
1558
+ void ModuleWrap::CreateCachedData (const FunctionCallbackInfo<Value>& args) {
1559
+ Isolate* isolate = args.GetIsolate ();
1560
+ Local<Object> that = args.This ();
1561
+
1562
+ ModuleWrap* obj;
1563
+ ASSIGN_OR_RETURN_UNWRAP (&obj, that);
1564
+
1565
+ CHECK (!obj->synthetic_ );
1566
+
1567
+ Local<Module> module = obj->module_ .Get (isolate);
1568
+
1569
+ CHECK_LT (module->GetStatus (), v8::Module::Status::kEvaluating );
1570
+
1571
+ Local<UnboundModuleScript> unbound_module_script =
1572
+ module->GetUnboundModuleScript ();
1573
+ std::unique_ptr<ScriptCompiler::CachedData> cached_data (
1574
+ ScriptCompiler::CreateCodeCache (unbound_module_script));
1575
+ Environment* env = Environment::GetCurrent (args);
1576
+ if (!cached_data) {
1577
+ args.GetReturnValue ().Set (Buffer::New (env, 0 ).ToLocalChecked ());
1578
+ } else {
1579
+ MaybeLocal<Object> buf =
1580
+ Buffer::Copy (env,
1581
+ reinterpret_cast <const char *>(cached_data->data ),
1582
+ cached_data->length );
1583
+ args.GetReturnValue ().Set (buf.ToLocalChecked ());
1584
+ }
1585
+ }
1586
+
1531
1587
void ModuleWrap::Initialize (Local<Object> target,
1532
1588
Local<Value> unused,
1533
1589
Local<Context> context,
@@ -1543,6 +1599,7 @@ void ModuleWrap::Initialize(Local<Object> target,
1543
1599
env->SetProtoMethod (tpl, " instantiate" , Instantiate);
1544
1600
env->SetProtoMethod (tpl, " evaluate" , Evaluate);
1545
1601
env->SetProtoMethod (tpl, " setExport" , SetSyntheticExport);
1602
+ env->SetProtoMethodNoSideEffect (tpl, " createCachedData" , CreateCachedData);
1546
1603
env->SetProtoMethodNoSideEffect (tpl, " getNamespace" , GetNamespace);
1547
1604
env->SetProtoMethodNoSideEffect (tpl, " getStatus" , GetStatus);
1548
1605
env->SetProtoMethodNoSideEffect (tpl, " getError" , GetError);
0 commit comments