diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 3aa7986bf17e26..3cf3f5c37cee26 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -1564,9 +1564,13 @@ Local ContextifyContext::CompileFunctionAndCacheResult( return Object::New(env->isolate()); std::unique_ptr new_cached_data; - if (produce_cached_data) { - new_cached_data.reset(ScriptCompiler::CreateCodeCacheForFunction(fn)); + if (produce_cached_data && !fn.IsEmpty()) { + TryCatchScope try_cache(env); + if (options != ScriptCompiler::kConsumeCodeCache) { + new_cached_data.reset(ScriptCompiler::CreateCodeCacheForFunction(fn)); + } } + if (StoreCodeCacheResult(env, result, options, diff --git a/test/parallel/test-vm-cached-data-validation.js b/test/parallel/test-vm-cached-data-validation.js new file mode 100644 index 00000000000000..bbfa87cd7a84a2 --- /dev/null +++ b/test/parallel/test-vm-cached-data-validation.js @@ -0,0 +1,33 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +// Test that creating cached data for an empty function doesn't crash +{ + const script = new vm.Script(''); + // Get cached data from empty script + const cachedData = script.createCachedData(); + + // Previously this would trigger a fatal V8 error: + // FATAL ERROR: v8::ScriptCompiler::CreateCodeCacheForFunction Expected SharedFunctionInfo with wrapped source code + vm.compileFunction('', undefined, { + cachedData, + produceCachedData: true + }); +} + +// Test normal case with actual function content still works +{ + const script = new vm.Script('function test() { return 42; }'); + const cachedData = script.createCachedData(); + + const fn = vm.compileFunction('return 42', undefined, { + cachedData, + produceCachedData: true + }); + + const expected = 42; + assert.strictEqual(fn(), expected); +}