@@ -281,6 +281,15 @@ void ContextifyContext::WeakCallback(
281281 delete context;
282282}
283283
284+ void ContextifyContext::WeakCallbackCompileFn (
285+ const WeakCallbackInfo<CompileFnEntry>& data) {
286+ CompileFnEntry* entry = data.GetParameter ();
287+ if (entry->env ->compile_fn_entries .erase (entry) != 0 ) {
288+ entry->env ->id_to_function_map .erase (entry->id );
289+ delete entry;
290+ }
291+ }
292+
284293// static
285294ContextifyContext* ContextifyContext::ContextFromContextifiedSandbox (
286295 Environment* env,
@@ -1039,7 +1048,30 @@ void ContextifyContext::CompileFunction(
10391048 data + cached_data_buf->ByteOffset (), cached_data_buf->ByteLength ());
10401049 }
10411050
1042- ScriptOrigin origin (filename, line_offset, column_offset);
1051+ // Get the function id
1052+ uint32_t id = env->get_next_function_id ();
1053+
1054+ // Set host_defined_options
1055+ Local<PrimitiveArray> host_defined_options =
1056+ PrimitiveArray::New (isolate, loader::HostDefinedOptions::kLength );
1057+ host_defined_options->Set (
1058+ isolate,
1059+ loader::HostDefinedOptions::kType ,
1060+ Number::New (isolate, loader::ScriptType::kFunction ));
1061+ host_defined_options->Set (
1062+ isolate, loader::HostDefinedOptions::kID , Number::New (isolate, id));
1063+
1064+ ScriptOrigin origin (filename,
1065+ line_offset, // line offset
1066+ column_offset, // column offset
1067+ True (isolate), // is cross origin
1068+ Local<Integer>(), // script id
1069+ Local<Value>(), // source map URL
1070+ False (isolate), // is opaque (?)
1071+ False (isolate), // is WASM
1072+ False (isolate), // is ES Module
1073+ host_defined_options);
1074+
10431075 ScriptCompiler::Source source (code, origin, cached_data);
10441076 ScriptCompiler::CompileOptions options;
10451077 if (source.GetCachedData () == nullptr ) {
@@ -1073,38 +1105,45 @@ void ContextifyContext::CompileFunction(
10731105 }
10741106 }
10751107
1076- MaybeLocal<Function> maybe_fun = ScriptCompiler::CompileFunctionInContext (
1108+ MaybeLocal<Function> maybe_fn = ScriptCompiler::CompileFunctionInContext (
10771109 parsing_context, &source, params.size (), params.data (),
10781110 context_extensions.size (), context_extensions.data (), options);
10791111
1080- Local<Function> fun;
1081- if (maybe_fun.IsEmpty () || !maybe_fun.ToLocal (&fun)) {
1112+ if (maybe_fn.IsEmpty ()) {
10821113 ContextifyScript::DecorateErrorStack (env, try_catch);
10831114 try_catch.ReThrow ();
10841115 return ;
10851116 }
1117+ Local<Function> fn = maybe_fn.ToLocalChecked ();
1118+ env->id_to_function_map .emplace (std::piecewise_construct,
1119+ std::make_tuple (id),
1120+ std::make_tuple (isolate, fn));
1121+ CompileFnEntry* gc_entry = new CompileFnEntry (env, id);
1122+ env->id_to_function_map [id].SetWeak (gc_entry,
1123+ WeakCallbackCompileFn,
1124+ v8::WeakCallbackType::kParameter );
10861125
10871126 if (produce_cached_data) {
10881127 const std::unique_ptr<ScriptCompiler::CachedData> cached_data (
1089- ScriptCompiler::CreateCodeCacheForFunction (fun ));
1128+ ScriptCompiler::CreateCodeCacheForFunction (fn ));
10901129 bool cached_data_produced = cached_data != nullptr ;
10911130 if (cached_data_produced) {
10921131 MaybeLocal<Object> buf = Buffer::Copy (
10931132 env,
10941133 reinterpret_cast <const char *>(cached_data->data ),
10951134 cached_data->length );
1096- if (fun ->Set (
1135+ if (fn ->Set (
10971136 parsing_context,
10981137 env->cached_data_string (),
10991138 buf.ToLocalChecked ()).IsNothing ()) return ;
11001139 }
1101- if (fun ->Set (
1140+ if (fn ->Set (
11021141 parsing_context,
11031142 env->cached_data_produced_string (),
11041143 Boolean::New (isolate, cached_data_produced)).IsNothing ()) return ;
11051144 }
11061145
1107- args.GetReturnValue ().Set (fun );
1146+ args.GetReturnValue ().Set (fn );
11081147}
11091148
11101149
0 commit comments