| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent b338edb commit 54896a6
13 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -39,7 +39,6 @@ let isDeepEqual; | |||
| 39 | 39 | let isDeepStrictEqual; | |
| 40 | 40 | let parseExpressionAt; | |
| 41 | 41 | let findNodeAround; | |
| 42 | - let columnOffset = 0; | ||
| 43 | 42 | let decoder; | |
| 44 | 43 | ||
| 45 | 44 | function lazyLoadComparison() { | |
@@ -256,16 +255,6 @@ function getErrMessage(message, fn) { | |||
| 256 | 255 | const line = call.getLineNumber() - 1; | |
| 257 | 256 | let column = call.getColumnNumber() - 1; | |
| 258 | 257 | ||
| 259 | - // Line number one reports the wrong column due to being wrapped in a | ||
| 260 | - // function. Remove that offset to get the actual call. | ||
| 261 | - if (line === 0) { | ||
| 262 | - if (columnOffset === 0) { | ||
| 263 | - const { wrapper } = require('internal/modules/cjs/loader'); | ||
| 264 | - columnOffset = wrapper[0].length; | ||
| 265 | - } | ||
| 266 | - column -= columnOffset; | ||
| 267 | - } | ||
| 268 | - | ||
| 269 | 258 | const identifier = `${filename}${line}${column}`; | |
| 270 | 259 | ||
| 271 | 260 | if (errorCache.has(identifier)) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,9 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { validateString } = require('internal/validators'); | |
| 4 | + const path = require('path'); | ||
| 5 | + const { pathToFileURL } = require('internal/url'); | ||
| 6 | + const { URL } = require('url'); | ||
| 4 | 7 | ||
| 5 | 8 | const { | |
| 6 | 9 | CHAR_LINE_FEED, | |
@@ -145,10 +148,18 @@ function addBuiltinLibsToObject(object) { | |||
| 145 | 148 | }); | |
| 146 | 149 | } | |
| 147 | 150 | ||
| 151 | + function normalizeReferrerURL(referrer) { | ||
| 152 | + if (typeof referrer === 'string' && path.isAbsolute(referrer)) { | ||
| 153 | + return pathToFileURL(referrer).href; | ||
| 154 | + } | ||
| 155 | + return new URL(referrer).href; | ||
| 156 | + } | ||
| 157 | + | ||
| 148 | 158 | module.exports = exports = { | |
| 149 | 159 | addBuiltinLibsToObject, | |
| 150 | 160 | builtinLibs, | |
| 151 | 161 | makeRequireFunction, | |
| 162 | + normalizeReferrerURL, | ||
| 152 | 163 | requireDepth: 0, | |
| 153 | 164 | stripBOM, | |
| 154 | 165 | stripShebang | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -29,14 +29,14 @@ const assert = require('internal/assert'); | |||
| 29 | 29 | const fs = require('fs'); | |
| 30 | 30 | const internalFS = require('internal/fs/utils'); | |
| 31 | 31 | const path = require('path'); | |
| 32 | - const { URL } = require('url'); | ||
| 33 | 32 | const { | |
| 34 | 33 | internalModuleReadJSON, | |
| 35 | 34 | internalModuleStat | |
| 36 | 35 | } = internalBinding('fs'); | |
| 37 | 36 | const { safeGetenv } = internalBinding('credentials'); | |
| 38 | 37 | const { | |
| 39 | 38 | makeRequireFunction, | |
| 39 | + normalizeReferrerURL, | ||
| 40 | 40 | requireDepth, | |
| 41 | 41 | stripBOM, | |
| 42 | 42 | stripShebang | |
@@ -48,6 +48,7 @@ const experimentalModules = getOptionValue('--experimental-modules'); | |||
| 48 | 48 | const manifest = getOptionValue('--experimental-policy') ? | |
| 49 | 49 | require('internal/process/policy').manifest : | |
| 50 | 50 | null; | |
| 51 | + const { compileFunction } = internalBinding('contextify'); | ||
| 51 | 52 | ||
| 52 | 53 | const { | |
| 53 | 54 | ERR_INVALID_ARG_VALUE, | |
@@ -129,15 +130,52 @@ Module._extensions = Object.create(null); | |||
| 129 | 130 | var modulePaths = []; | |
| 130 | 131 | Module.globalPaths = []; | |
| 131 | 132 | ||
| 132 | - Module.wrap = function(script) { | ||
| 133 | + let patched = false; | ||
| 134 | + | ||
| 135 | + // eslint-disable-next-line func-style | ||
| 136 | + let wrap = function(script) { | ||
| 133 | 137 | return Module.wrapper[0] + script + Module.wrapper[1]; | |
| 134 | 138 | }; | |
| 135 | 139 | ||
| 136 | - Module.wrapper = [ | ||
| 140 | + const wrapper = [ | ||
| 137 | 141 | '(function (exports, require, module, __filename, __dirname) { ', | |
| 138 | 142 | '\n});' | |
| 139 | 143 | ]; | |
| 140 | 144 | ||
| 145 | + let wrapperProxy = new Proxy(wrapper, { | ||
| 146 | + set(target, property, value, receiver) { | ||
| 147 | + patched = true; | ||
| 148 | + return Reflect.set(target, property, value, receiver); | ||
| 149 | + }, | ||
| 150 | + | ||
| 151 | + defineProperty(target, property, descriptor) { | ||
| 152 | + patched = true; | ||
| 153 | + return Object.defineProperty(target, property, descriptor); | ||
| 154 | + } | ||
| 155 | + }); | ||
| 156 | + | ||
| 157 | + Object.defineProperty(Module, 'wrap', { | ||
| 158 | + get() { | ||
| 159 | + return wrap; | ||
| 160 | + }, | ||
| 161 | + | ||
| 162 | + set(value) { | ||
| 163 | + patched = true; | ||
| 164 | + wrap = value; | ||
| 165 | + } | ||
| 166 | + }); | ||
| 167 | + | ||
| 168 | + Object.defineProperty(Module, 'wrapper', { | ||
| 169 | + get() { | ||
| 170 | + return wrapperProxy; | ||
| 171 | + }, | ||
| 172 | + | ||
| 173 | + set(value) { | ||
| 174 | + patched = true; | ||
| 175 | + wrapperProxy = value; | ||
| 176 | + } | ||
| 177 | + }); | ||
| 178 | + | ||
| 141 | 179 | const debug = util.debuglog('module'); | |
| 142 | 180 | ||
| 143 | 181 | Module._debug = util.deprecate(debug, 'Module._debug is deprecated.', | |
@@ -672,13 +710,6 @@ Module.prototype.require = function(id) { | |||
| 672 | 710 | // (needed for setting breakpoint when called with --inspect-brk) | |
| 673 | 711 | var resolvedArgv; | |
| 674 | 712 | ||
| 675 | - function normalizeReferrerURL(referrer) { | ||
| 676 | - if (typeof referrer === 'string' && path.isAbsolute(referrer)) { | ||
| 677 | - return pathToFileURL(referrer).href; | ||
| 678 | - } | ||
| 679 | - return new URL(referrer).href; | ||
| 680 | - } | ||
| 681 | - | ||
| 682 | 713 | ||
| 683 | 714 | // Run the file contents in the correct scope or sandbox. Expose | |
| 684 | 715 | // the correct helper variables (require, module, exports) to | |
@@ -692,13 +723,48 @@ Module.prototype._compile = function(content, filename) { | |||
| 692 | 723 | ||
| 693 | 724 | content = stripShebang(content); | |
| 694 | 725 | ||
| 695 | - const compiledWrapper = vm.compileFunction(content, [ | ||
| 696 | - 'exports', | ||
| 697 | - 'require', | ||
| 698 | - 'module', | ||
| 699 | - '__filename', | ||
| 700 | - '__dirname', | ||
| 701 | - ], { filename }); | ||
| 726 | + let compiledWrapper; | ||
| 727 | + if (patched) { | ||
| 728 | + const wrapper = Module.wrap(content); | ||
| 729 | + compiledWrapper = vm.runInThisContext(wrapper, { | ||
| 730 | + filename, | ||
| 731 | + lineOffset: 0, | ||
| 732 | + displayErrors: true, | ||
| 733 | + importModuleDynamically: experimentalModules ? async (specifier) => { | ||
| 734 | + if (asyncESM === undefined) lazyLoadESM(); | ||
| 735 | + const loader = await asyncESM.loaderPromise; | ||
| 736 | + return loader.import(specifier, normalizeReferrerURL(filename)); | ||
| 737 | + } : undefined, | ||
| 738 | + }); | ||
| 739 | + } else { | ||
| 740 | + compiledWrapper = compileFunction( | ||
| 741 | + content, | ||
| 742 | + filename, | ||
| 743 | + 0, | ||
| 744 | + 0, | ||
| 745 | + undefined, | ||
| 746 | + false, | ||
| 747 | + undefined, | ||
| 748 | + [], | ||
| 749 | + [ | ||
| 750 | + 'exports', | ||
| 751 | + 'require', | ||
| 752 | + 'module', | ||
| 753 | + '__filename', | ||
| 754 | + '__dirname', | ||
| 755 | + ] | ||
| 756 | + ); | ||
| 757 | + if (experimentalModules) { | ||
| 758 | + const { callbackMap } = internalBinding('module_wrap'); | ||
| 759 | + callbackMap.set(compiledWrapper, { | ||
| 760 | + importModuleDynamically: async (specifier) => { | ||
| 761 | + if (asyncESM === undefined) lazyLoadESM(); | ||
| 762 | + const loader = await asyncESM.loaderPromise; | ||
| 763 | + return loader.import(specifier, normalizeReferrerURL(filename)); | ||
| 764 | + } | ||
| 765 | + }); | ||
| 766 | + } | ||
| 767 | + } | ||
| 702 | 768 | ||
| 703 | 769 | var inspectorWrapper = null; | |
| 704 | 770 | if (process._breakFirstLine && process._eval == null) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -461,6 +461,9 @@ inline uint32_t Environment::get_next_module_id() { | |||
| 461 | 461 | inline uint32_t Environment::get_next_script_id() { | |
| 462 | 462 | return script_id_counter_++; | |
| 463 | 463 | } | |
| 464 | + inline uint32_t Environment::get_next_function_id() { | ||
| 465 | + return function_id_counter_++; | ||
| 466 | + } | ||
| 464 | 467 | ||
| 465 | 468 | Environment::ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope( | |
| 466 | 469 | Environment* env) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -252,6 +252,11 @@ Environment::Environment(IsolateData* isolate_data, | |||
| 252 | 252 | isolate()->SetPromiseRejectCallback(task_queue::PromiseRejectCallback); | |
| 253 | 253 | } | |
| 254 | 254 | ||
| 255 | + CompileFnEntry::CompileFnEntry(Environment* env, uint32_t id) | ||
| 256 | + : env(env), id(id) { | ||
| 257 | + env->compile_fn_entries.insert(this); | ||
| 258 | + } | ||
| 259 | + | ||
| 255 | 260 | Environment::~Environment() { | |
| 256 | 261 | isolate()->GetHeapProfiler()->RemoveBuildEmbedderGraphCallback( | |
| 257 | 262 | BuildEmbedderGraph, this); | |
@@ -260,6 +265,12 @@ Environment::~Environment() { | |||
| 260 | 265 | // CleanupHandles() should have removed all of them. | |
| 261 | 266 | CHECK(file_handle_read_wrap_freelist_.empty()); | |
| 262 | 267 | ||
| 268 | + // dispose the Persistent references to the compileFunction | ||
| 269 | + // wrappers used in the dynamic import callback | ||
| 270 | + for (auto& entry : compile_fn_entries) { | ||
| 271 | + delete entry; | ||
| 272 | + } | ||
| 273 | + | ||
| 263 | 274 | HandleScope handle_scope(isolate()); | |
| 264 | 275 | ||
| 265 | 276 | #if HAVE_INSPECTOR | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -448,6 +448,12 @@ struct ContextInfo { | |||
| 448 | 448 | bool is_default = false; | |
| 449 | 449 | }; | |
| 450 | 450 | ||
| 451 | + struct CompileFnEntry { | ||
| 452 | + Environment* env; | ||
| 453 | + uint32_t id; | ||
| 454 | + CompileFnEntry(Environment* env, uint32_t id); | ||
| 455 | + }; | ||
| 456 | + | ||
| 451 | 457 | // Listing the AsyncWrap provider types first enables us to cast directly | |
| 452 | 458 | // from a provider type to a debug category. | |
| 453 | 459 | #define DEBUG_CATEGORY_NAMES(V) \ | |
@@ -718,9 +724,12 @@ class Environment { | |||
| 718 | 724 | std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map; | |
| 719 | 725 | std::unordered_map<uint32_t, contextify::ContextifyScript*> | |
| 720 | 726 | id_to_script_map; | |
| 727 | + std::unordered_set<CompileFnEntry*> compile_fn_entries; | ||
| 728 | + std::unordered_map<uint32_t, Persistent<v8::Function>> id_to_function_map; | ||
| 721 | 729 | ||
| 722 | 730 | inline uint32_t get_next_module_id(); | |
| 723 | 731 | inline uint32_t get_next_script_id(); | |
| 732 | + inline uint32_t get_next_function_id(); | ||
| 724 | 733 | ||
| 725 | 734 | std::unordered_map<std::string, const loader::PackageConfig> | |
| 726 | 735 | package_json_cache; | |
@@ -1010,6 +1019,7 @@ class Environment { | |||
| 1010 | 1019 | ||
| 1011 | 1020 | uint32_t module_id_counter_ = 0; | |
| 1012 | 1021 | uint32_t script_id_counter_ = 0; | |
| 1022 | + uint32_t function_id_counter_ = 0; | ||
| 1013 | 1023 | ||
| 1014 | 1024 | AliasedBuffer<uint32_t, v8::Uint32Array> should_abort_on_uncaught_toggle_; | |
| 1015 | 1025 | int should_not_abort_scope_counter_ = 0; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -752,6 +752,8 @@ static MaybeLocal<Promise> ImportModuleDynamically( | |||
| 752 | 752 | } else if (type == ScriptType::kModule) { | |
| 753 | 753 | ModuleWrap* wrap = ModuleWrap::GetFromID(env, id); | |
| 754 | 754 | object = wrap->object(); | |
| 755 | + } else if (type == ScriptType::kFunction) { | ||
| 756 | + object = env->id_to_function_map.find(id)->second.Get(iso); | ||
| 755 | 757 | } else { | |
| 756 | 758 | UNREACHABLE(); | |
| 757 | 759 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,7 @@ enum PackageMainCheck : bool { | |||
| 20 | 20 | enum ScriptType : int { | |
| 21 | 21 | kScript, | |
| 22 | 22 | kModule, | |
| 23 | + kFunction, | ||
| 23 | 24 | }; | |
| 24 | 25 | ||
| 25 | 26 | enum HostDefinedOptions : int { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -285,6 +285,15 @@ void ContextifyContext::WeakCallback( | |||
| 285 | 285 | delete context; | |
| 286 | 286 | } | |
| 287 | 287 | ||
| 288 | + void ContextifyContext::WeakCallbackCompileFn( | ||
| 289 | + const WeakCallbackInfo<CompileFnEntry>& data) { | ||
| 290 | + CompileFnEntry* entry = data.GetParameter(); | ||
| 291 | + if (entry->env->compile_fn_entries.erase(entry) != 0) { | ||
| 292 | + entry->env->id_to_function_map.erase(entry->id); | ||
| 293 | + delete entry; | ||
| 294 | + } | ||
| 295 | + } | ||
| 296 | + | ||
| 288 | 297 | // static | |
| 289 | 298 | ContextifyContext* ContextifyContext::ContextFromContextifiedSandbox( | |
| 290 | 299 | Environment* env, | |
@@ -1027,7 +1036,30 @@ void ContextifyContext::CompileFunction( | |||
| 1027 | 1036 | data + cached_data_buf->ByteOffset(), cached_data_buf->ByteLength()); | |
| 1028 | 1037 | } | |
| 1029 | 1038 | ||
| 1030 | - ScriptOrigin origin(filename, line_offset, column_offset, True(isolate)); | ||
| 1039 | + // Get the function id | ||
| 1040 | + uint32_t id = env->get_next_function_id(); | ||
| 1041 | + | ||
| 1042 | + // Set host_defined_options | ||
| 1043 | + Local<PrimitiveArray> host_defined_options = | ||
| 1044 | + PrimitiveArray::New(isolate, loader::HostDefinedOptions::kLength); | ||
| 1045 | + host_defined_options->Set( | ||
| 1046 | + isolate, | ||
| 1047 | + loader::HostDefinedOptions::kType, | ||
| 1048 | + Number::New(isolate, loader::ScriptType::kFunction)); | ||
| 1049 | + host_defined_options->Set( | ||
| 1050 | + isolate, loader::HostDefinedOptions::kID, Number::New(isolate, id)); | ||
| 1051 | + | ||
| 1052 | + ScriptOrigin origin(filename, | ||
| 1053 | + line_offset, // line offset | ||
| 1054 | + column_offset, // column offset | ||
| 1055 | + True(isolate), // is cross origin | ||
| 1056 | + Local<Integer>(), // script id | ||
| 1057 | + Local<Value>(), // source map URL | ||
| 1058 | + False(isolate), // is opaque (?) | ||
| 1059 | + False(isolate), // is WASM | ||
| 1060 | + False(isolate), // is ES Module | ||
| 1061 | + host_defined_options); | ||
| 1062 | + | ||
| 1031 | 1063 | ScriptCompiler::Source source(code, origin, cached_data); | |
| 1032 | 1064 | ScriptCompiler::CompileOptions options; | |
| 1033 | 1065 | if (source.GetCachedData() == nullptr) { | |
@@ -1061,38 +1093,45 @@ void ContextifyContext::CompileFunction( | |||
| 1061 | 1093 | } | |
| 1062 | 1094 | } | |
| 1063 | 1095 | ||
| 1064 | - MaybeLocal<Function> maybe_fun = ScriptCompiler::CompileFunctionInContext( | ||
| 1096 | + MaybeLocal<Function> maybe_fn = ScriptCompiler::CompileFunctionInContext( | ||
| 1065 | 1097 | parsing_context, &source, params.size(), params.data(), | |
| 1066 | 1098 | context_extensions.size(), context_extensions.data(), options); | |
| 1067 | 1099 | ||
| 1068 | - Local<Function> fun; | ||
| 1069 | - if (maybe_fun.IsEmpty() || !maybe_fun.ToLocal(&fun)) { | ||
| 1100 | + if (maybe_fn.IsEmpty()) { | ||
| 1070 | 1101 | DecorateErrorStack(env, try_catch); | |
| 1071 | 1102 | try_catch.ReThrow(); | |
| 1072 | 1103 | return; | |
| 1073 | 1104 | } | |
| 1105 | + Local<Function> fn = maybe_fn.ToLocalChecked(); | ||
| 1106 | + env->id_to_function_map.emplace(std::piecewise_construct, | ||
| 1107 | + std::make_tuple(id), | ||
| 1108 | + std::make_tuple(isolate, fn)); | ||
| 1109 | + CompileFnEntry* gc_entry = new CompileFnEntry(env, id); | ||
| 1110 | + env->id_to_function_map[id].SetWeak(gc_entry, | ||
| 1111 | + WeakCallbackCompileFn, | ||
| 1112 | + v8::WeakCallbackType::kParameter); | ||
| 1074 | 1113 | ||
| 1075 | 1114 | if (produce_cached_data) { | |
| 1076 | 1115 | const std::unique_ptr<ScriptCompiler::CachedData> cached_data( | |
| 1077 | - ScriptCompiler::CreateCodeCacheForFunction(fun)); | ||
| 1116 | + ScriptCompiler::CreateCodeCacheForFunction(fn)); | ||
| 1078 | 1117 | bool cached_data_produced = cached_data != nullptr; | |
| 1079 | 1118 | if (cached_data_produced) { | |
| 1080 | 1119 | MaybeLocal<Object> buf = Buffer::Copy( | |
| 1081 | 1120 | env, | |
| 1082 | 1121 | reinterpret_cast<const char*>(cached_data->data), | |
| 1083 | 1122 | cached_data->length); | |
| 1084 | - if (fun->Set( | ||
| 1123 | + if (fn->Set( | ||
| 1085 | 1124 | parsing_context, | |
| 1086 | 1125 | env->cached_data_string(), | |
| 1087 | 1126 | buf.ToLocalChecked()).IsNothing()) return; | |
| 1088 | 1127 | } | |
| 1089 | - if (fun->Set( | ||
| 1128 | + if (fn->Set( | ||
| 1090 | 1129 | parsing_context, | |
| 1091 | 1130 | env->cached_data_produced_string(), | |
| 1092 | 1131 | Boolean::New(isolate, cached_data_produced)).IsNothing()) return; | |
| 1093 | 1132 | } | |
| 1094 | 1133 | ||
| 1095 | - args.GetReturnValue().Set(fun); | ||
| 1134 | + args.GetReturnValue().Set(fn); | ||
| 1096 | 1135 | } | |
| 1097 | 1136 | ||
| 1098 | 1137 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -61,6 +61,8 @@ class ContextifyContext { | |||
| 61 | 61 | const v8::FunctionCallbackInfo<v8::Value>& args); | |
| 62 | 62 | static void WeakCallback( | |
| 63 | 63 | const v8::WeakCallbackInfo<ContextifyContext>& data); | |
| 64 | + static void WeakCallbackCompileFn( | ||
| 65 | + const v8::WeakCallbackInfo<CompileFnEntry>& data); | ||
| 64 | 66 | static void PropertyGetterCallback( | |
| 65 | 67 | v8::Local<v8::Name> property, | |
| 66 | 68 | const v8::PropertyCallbackInfo<v8::Value>& args); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments