| 1134 | // underlying V8 issue is: |
| 1135 | // https://code.google.com/p/v8/issues/detail?id=1281 |
| 1136 | export function runJavaScript(code: string, { |
| 1137 | symbols = Object.create(null), |
| 1138 | filename = "<anonymous>", |
| 1139 | sourceMap, |
| 1140 | sourceMapRoot, |
| 1141 | }: { |
| 1142 | symbols: Record<string, any>; |
| 1143 | filename: string; |
| 1144 | sourceMap?: object; |
| 1145 | sourceMapRoot?: string; |
| 1146 | }) { |
| 1147 | return Profile.time('runJavaScript ' + filename, () => { |
| 1148 | const keys: string[] = [], values: any[] = []; |
| 1149 | // don't assume that _.keys and _.values are guaranteed to |
| 1150 | // enumerate in the same order |
| 1151 | _.each(symbols, function (value: any, name: string) { |
| 1152 | keys.push(name); |
| 1153 | values.push(value); |
| 1154 | }); |
| 1155 | |
| 1156 | let stackFilename = filename; |
| 1157 | if (sourceMap) { |
| 1158 | // We want to generate an arbitrary filename that we use to associate the |
| 1159 | // file with its source map. |
| 1160 | stackFilename = "<runJavaScript-" + nextStackFilenameCounter++ + ">"; |
| 1161 | } |
| 1162 | |
| 1163 | const chunks = []; |
| 1164 | const header = "(function(" + keys.join(',') + "){"; |
| 1165 | chunks.push(header); |
| 1166 | if (sourceMap) { |
| 1167 | chunks.push(sourcemap.SourceNode.fromStringWithSourceMap( |
| 1168 | code, new sourcemap.SourceMapConsumer(sourceMap))); |
| 1169 | } else { |
| 1170 | chunks.push(code); |
| 1171 | } |
| 1172 | // \n is necessary in case final line is a //-comment |
| 1173 | chunks.push("\n})"); |
| 1174 | |
| 1175 | let wrapped; |
| 1176 | let parsedSourceMap = null; |
| 1177 | if (sourceMap) { |
| 1178 | const results = new sourcemap.SourceNode( |
| 1179 | null, null, null, chunks |
| 1180 | ).toStringWithSourceMap({ |
| 1181 | file: stackFilename |
| 1182 | }); |
| 1183 | wrapped = results.code; |
| 1184 | parsedSourceMap = results.map.toJSON(); |
| 1185 | if (sourceMapRoot) { |
| 1186 | // Add the specified root to any root that may be in the file. |
| 1187 | parsedSourceMap.sourceRoot = pathJoin( |
| 1188 | sourceMapRoot, parsedSourceMap.sourceRoot || ''); |
| 1189 | } |
| 1190 | // source-map-support doesn't ever look at the sourcesContent field, so |
| 1191 | // there's no point in keeping it in memory. |
| 1192 | delete parsedSourceMap.sourcesContent; |
| 1193 | parsedSourceMaps[stackFilename] = parsedSourceMap; |