Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library builtin; | 5 library builtin; |
| 6 import 'dart:io'; | |
| 7 import 'dart:async'; | 6 import 'dart:async'; |
| 8 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:isolate'; | |
| 9 | |
| 10 | |
| 11 /* See Dart_LibraryTag in dart_api.h */ | |
| 12 const Dart_kScriptTag = null; | |
| 13 const Dart_kImportTag = 0; | |
| 14 const Dart_kSourceTag = 1; | |
| 15 const Dart_kCanonicalizeUrl = 2; | |
| 16 | |
| 17 // Dart native extension scheme. | |
| 18 const _DART_EXT = 'dart-ext:'; | |
| 19 | |
| 9 // import 'root_library'; happens here from C Code | 20 // import 'root_library'; happens here from C Code |
| 10 | 21 |
| 11 // The root library (aka the script) is imported into this library. The | 22 // The root library (aka the script) is imported into this library. The |
| 12 // standalone embedder uses this to lookup the main entrypoint in the | 23 // standalone embedder uses this to lookup the main entrypoint in the |
| 13 // root library's namespace. | 24 // root library's namespace. |
| 14 Function _getMainClosure() => main; | 25 Function _getMainClosure() => main; |
| 15 | 26 |
| 27 // A port for communicating with the service isolate for I/O. | |
| 28 SendPort _loadPort; | |
| 29 | |
| 30 const _logBuiltin = false; | |
| 16 | 31 |
| 17 // Corelib 'print' implementation. | 32 // Corelib 'print' implementation. |
| 18 void _print(arg) { | 33 void _print(arg) { |
| 19 _Logger._printString(arg.toString()); | 34 _Logger._printString(arg.toString()); |
| 20 } | 35 } |
| 21 | 36 |
| 22 | |
| 23 class _Logger { | 37 class _Logger { |
| 24 static void _printString(String s) native "Logger_PrintString"; | 38 static void _printString(String s) native "Logger_PrintString"; |
| 25 } | 39 } |
| 26 | 40 |
| 27 | |
| 28 _getPrintClosure() => _print; | 41 _getPrintClosure() => _print; |
| 29 | 42 |
| 30 const _logBuiltin = false; | 43 _getCurrentDirectoryPath() native "Directory_Current"; |
|
siva
2015/01/22 22:39:31
see comment below about these native methods.
Cutch
2015/01/26 18:59:30
Directory_Current is part of the builtin natives.
| |
| 31 | 44 |
| 32 // Corelib 'Uri.base' implementation. | 45 // Corelib 'Uri.base' implementation. |
| 33 Uri _uriBase() { | 46 Uri _uriBase() { |
| 34 return new Uri.file(Directory.current.path + "/"); | 47 return new Uri.file(_getCurrentDirectoryPath() + "/"); |
| 35 } | 48 } |
| 36 | 49 |
| 37 | |
| 38 _getUriBaseClosure() => _uriBase; | 50 _getUriBaseClosure() => _uriBase; |
| 39 | 51 |
| 40 | 52 |
| 41 // Are we running on Windows? | 53 // Are we running on Windows? |
| 42 var _isWindows = false; | 54 var _isWindows = false; |
| 43 var _workingWindowsDrivePrefix; | 55 var _workingWindowsDrivePrefix; |
| 44 // The current working directory | 56 // The current working directory |
| 45 var _workingDirectoryUri; | 57 var _workingDirectoryUri; |
| 46 // The URI that the entry point script was loaded from. Remembered so that | 58 // The URI that the entry point script was loaded from. Remembered so that |
| 47 // package imports can be resolved relative to it. | 59 // package imports can be resolved relative to it. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 119 _packageRoot = _workingDirectoryUri.resolve(packageRoot); | 131 _packageRoot = _workingDirectoryUri.resolve(packageRoot); |
| 120 } else { | 132 } else { |
| 121 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); | 133 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); |
| 122 } | 134 } |
| 123 if (_logBuiltin) { | 135 if (_logBuiltin) { |
| 124 _print('# Package root: $packageRoot -> $_packageRoot'); | 136 _print('# Package root: $packageRoot -> $_packageRoot'); |
| 125 } | 137 } |
| 126 } | 138 } |
| 127 | 139 |
| 128 | 140 |
| 141 // Given a uri with a 'package' scheme, return a Uri that is prefixed with | |
| 142 // the package root. | |
| 143 Uri _resolvePackageUri(Uri uri) { | |
| 144 if (!uri.host.isEmpty) { | |
| 145 var path = '${uri.host}${uri.path}'; | |
| 146 var right = 'package:$path'; | |
| 147 var wrong = 'package://$path'; | |
| 148 | |
| 149 throw "URIs using the 'package:' scheme should look like " | |
| 150 "'$right', not '$wrong'."; | |
| 151 } | |
| 152 | |
| 153 var packageRoot = _packageRoot == null ? | |
| 154 _entryPointScript.resolve('packages/') : | |
| 155 _packageRoot; | |
| 156 return packageRoot.resolve(uri.path); | |
| 157 } | |
| 158 | |
| 159 | |
| 160 | |
| 129 String _resolveScriptUri(String scriptName) { | 161 String _resolveScriptUri(String scriptName) { |
| 130 if (_workingDirectoryUri == null) { | 162 if (_workingDirectoryUri == null) { |
| 131 throw 'No current working directory set.'; | 163 throw 'No current working directory set.'; |
| 132 } | 164 } |
| 133 scriptName = _sanitizeWindowsPath(scriptName); | 165 scriptName = _sanitizeWindowsPath(scriptName); |
| 134 | 166 |
| 135 var scriptUri = Uri.parse(scriptName); | 167 var scriptUri = Uri.parse(scriptName); |
| 136 if (scriptUri.scheme != '') { | 168 if (scriptUri.scheme != '') { |
| 137 // Script has a scheme, assume that it is fully formed. | 169 // Script has a scheme, assume that it is fully formed. |
| 138 _entryPointScript = scriptUri; | 170 _entryPointScript = scriptUri; |
| 139 } else { | 171 } else { |
| 140 // Script does not have a scheme, assume that it is a path, | 172 // Script does not have a scheme, assume that it is a path, |
| 141 // resolve it against the working directory. | 173 // resolve it against the working directory. |
| 142 _entryPointScript = _workingDirectoryUri.resolve(scriptName); | 174 _entryPointScript = _workingDirectoryUri.resolve(scriptName); |
| 143 } | 175 } |
| 144 if (_logBuiltin) { | 176 if (_logBuiltin) { |
| 145 _print('# Resolved entry point to: $_entryPointScript'); | 177 _print('# Resolved entry point to: $_entryPointScript'); |
| 146 } | 178 } |
| 147 return _entryPointScript.toString(); | 179 return _entryPointScript.toString(); |
| 148 } | 180 } |
| 149 | 181 |
| 150 const _DART_EXT = 'dart-ext:'; | |
| 151 | 182 |
| 183 // Function called by standalone embedder to resolve uris. | |
| 152 String _resolveUri(String base, String userString) { | 184 String _resolveUri(String base, String userString) { |
| 153 if (_logBuiltin) { | 185 if (_logBuiltin) { |
| 154 _print('# Resolving: $userString from $base'); | 186 _print('# Resolving: $userString from $base'); |
| 155 } | 187 } |
| 156 var baseUri = Uri.parse(base); | 188 var baseUri = Uri.parse(base); |
| 157 if (userString.startsWith(_DART_EXT)) { | 189 if (userString.startsWith(_DART_EXT)) { |
| 158 var uri = userString.substring(_DART_EXT.length); | 190 var uri = userString.substring(_DART_EXT.length); |
| 159 return '$_DART_EXT${baseUri.resolve(uri)}'; | 191 return '$_DART_EXT${baseUri.resolve(uri)}'; |
| 160 } else { | 192 } else { |
| 161 return baseUri.resolve(userString).toString(); | 193 return baseUri.resolve(userString).toString(); |
| 162 } | 194 } |
| 163 } | 195 } |
| 164 | 196 |
| 165 | 197 Uri _createUri(String userUri) { |
| 166 // Returns either a file path or a URI starting with http[s]:, as a String. | |
| 167 String _filePathFromUri(String userUri) { | |
| 168 var uri = Uri.parse(userUri); | 198 var uri = Uri.parse(userUri); |
| 169 if (_logBuiltin) { | |
| 170 _print('# Getting file path from: $uri'); | |
| 171 } | |
| 172 | |
| 173 var path; | |
| 174 switch (uri.scheme) { | 199 switch (uri.scheme) { |
| 175 case '': | 200 case '': |
| 176 case 'file': | 201 case 'file': |
| 177 return uri.toFilePath(); | |
| 178 case 'package': | |
| 179 return _filePathFromUri(_resolvePackageUri(uri).toString()); | |
| 180 case 'http': | 202 case 'http': |
| 181 case 'https': | 203 case 'https': |
| 182 return uri.toString(); | 204 return uri; |
| 205 case 'package': | |
| 206 return _resolvePackageUri(uri); | |
| 183 default: | 207 default: |
| 184 // Only handling file, http, and package URIs | 208 // Only handling file, http[s], and package URIs |
| 185 // in standalone binary. | 209 // in standalone binary. |
| 186 if (_logBuiltin) { | 210 if (_logBuiltin) { |
| 187 _print('# Unknown scheme (${uri.scheme}) in $uri.'); | 211 _print('# Unknown scheme (${uri.scheme}) in $uri.'); |
| 188 } | 212 } |
| 189 throw 'Not a known scheme: $uri'; | 213 throw 'Not a known scheme: $uri'; |
| 190 } | 214 } |
| 191 } | 215 } |
| 192 | 216 |
| 193 | 217 int _numOutstandingLoadRequests = 0; |
| 194 Uri _resolvePackageUri(Uri uri) { | 218 void _finishedOneLoadRequest(String uri) { |
| 195 if (!uri.host.isEmpty) { | 219 assert(_numOutstandingLoadRequests > 0); |
| 196 var path = '${uri.host}${uri.path}'; | 220 _numOutstandingLoadRequests--; |
| 197 var right = 'package:$path'; | 221 if (_logBuiltin) { |
| 198 var wrong = 'package://$path'; | 222 _print("Loading of $uri finished, " |
| 199 | 223 "${_numOutstandingLoadRequests} requests remaining"); |
| 200 throw "URIs using the 'package:' scheme should look like " | |
| 201 "'$right', not '$wrong'."; | |
| 202 } | 224 } |
| 203 | 225 if (_numOutstandingLoadRequests == 0) { |
| 204 var packageRoot = _packageRoot == null ? | 226 _signalDoneLoading(); |
| 205 _entryPointScript.resolve('packages/') : | |
| 206 _packageRoot; | |
| 207 return packageRoot.resolve(uri.path); | |
| 208 } | |
| 209 | |
| 210 | |
| 211 int _numOutstandingLoadRequests = 0; | |
| 212 var _httpClient; | |
| 213 | |
| 214 void _httpGet(Uri uri, String libraryUri, loadCallback(List<int> data)) { | |
| 215 if (_httpClient == null) { | |
| 216 _httpClient = new HttpClient()..maxConnectionsPerHost = 6; | |
| 217 } | |
| 218 _httpClient.getUrl(uri) | |
| 219 .then((HttpClientRequest request) => request.close()) | |
| 220 .then((HttpClientResponse response) { | |
| 221 var builder = new BytesBuilder(copy: false); | |
| 222 response.listen( | |
| 223 builder.add, | |
| 224 onDone: () { | |
| 225 if (response.statusCode != 200) { | |
| 226 var msg = 'Failure getting $uri: ' | |
| 227 '${response.statusCode} ${response.reasonPhrase}'; | |
| 228 _asyncLoadError(uri.toString(), libraryUri, msg); | |
| 229 } | |
| 230 loadCallback(builder.takeBytes()); | |
| 231 }, | |
| 232 onError: (error) { | |
| 233 _asyncLoadError(uri.toString(), libraryUri, error); | |
| 234 }); | |
| 235 }) | |
| 236 .catchError((error) { | |
| 237 _asyncLoadError(uri.toString(), libraryUri, error); | |
| 238 }); | |
| 239 // TODO(floitsch): remove this line. It's just here to push an event on the | |
| 240 // event loop so that we invoke the scheduled microtasks. Also remove the | |
| 241 // import of dart:async when this line is not needed anymore. | |
| 242 Timer.run(() {}); | |
| 243 } | |
| 244 | |
| 245 | |
| 246 void _signalDoneLoading() native "Builtin_DoneLoading"; | |
| 247 | |
| 248 void _cleanup() { | |
| 249 if (_httpClient != null) { | |
| 250 _httpClient.close(); | |
| 251 _httpClient = null; | |
| 252 } | 227 } |
| 253 } | 228 } |
| 254 | 229 |
| 230 void _startingOneLoadRequest(String uri) { | |
| 231 assert(_numOutstandingLoadRequests >= 0); | |
| 232 _numOutstandingLoadRequests++; | |
| 233 if (_logBuiltin) { | |
| 234 _print("Loading of $uri started, " | |
| 235 "${_numOutstandingLoadRequests} requests outstanding"); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 class LoadError extends Error { | |
| 240 final String message; | |
| 241 LoadError(this.message); | |
| 242 | |
| 243 String toString() => 'Load Error: $message'; | |
| 244 } | |
| 245 | |
| 246 void _signalDoneLoading() native "Builtin_DoneLoading"; | |
| 255 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data) | 247 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data) |
| 256 native "Builtin_LoadScript"; | 248 native "Builtin_LoadScript"; |
| 249 void _asyncLoadErrorCallback(uri, libraryUri, error) | |
| 250 native "Builtin_AsyncLoadError"; | |
| 257 | 251 |
| 258 void _loadScript(int tag, String uri, String libraryUri, List<int> data) { | 252 void _loadScript(int tag, String uri, String libraryUri, List<int> data) { |
| 259 // TODO: Currently a compilation error while loading the script is | 253 // TODO: Currently a compilation error while loading the script is |
| 260 // fatal for the isolate. _loadScriptCallback() does not return and | 254 // fatal for the isolate. _loadScriptCallback() does not return and |
| 261 // the _numOutstandingLoadRequests counter remains out of sync. | 255 // the _numOutstandingLoadRequests counter remains out of sync. |
| 262 _loadScriptCallback(tag, uri, libraryUri, data); | 256 _loadScriptCallback(tag, uri, libraryUri, data); |
| 263 assert(_numOutstandingLoadRequests > 0); | 257 _finishedOneLoadRequest(uri); |
| 264 _numOutstandingLoadRequests--; | 258 } |
| 259 | |
| 260 void _asyncLoadError(tag, uri, libraryUri, error) { | |
| 265 if (_logBuiltin) { | 261 if (_logBuiltin) { |
| 266 _print("native Builtin_LoadScript($uri) completed, " | 262 _print("_asyncLoadError($uri), error: $error"); |
| 267 "${_numOutstandingLoadRequests} requests remaining"); | |
| 268 } | 263 } |
| 269 if (_numOutstandingLoadRequests == 0) { | 264 if (tag == Dart_kImportTag) { |
| 270 _signalDoneLoading(); | 265 // When importing a library, the libraryUri is the imported |
| 271 _cleanup(); | 266 // uri. |
| 267 libraryUri = uri; | |
| 268 } | |
| 269 _asyncLoadErrorCallback(uri, libraryUri, new LoadError(error)); | |
| 270 _finishedOneLoadRequest(uri); | |
| 271 } | |
| 272 | |
| 273 | |
| 274 // Asynchronously loads script data through a http[s] or file uri. | |
| 275 _loadDataAsync(int tag, String uri, String libraryUri) { | |
| 276 if (tag == Dart_kScriptTag) { | |
| 277 uri = _resolveScriptUri(uri); | |
| 278 } | |
| 279 | |
| 280 Uri resourceUri = _createUri(uri); | |
| 281 | |
| 282 var receivePort = new ReceivePort(); | |
| 283 receivePort.first.then((dataOrError) { | |
| 284 if (dataOrError is List<int>) { | |
| 285 _loadScript(tag, uri, libraryUri, dataOrError); | |
| 286 } else { | |
| 287 _asyncLoadError(tag, uri, libraryUri, dataOrError); | |
| 288 } | |
| 289 }).catchError((e) { | |
| 290 _asyncLoadError(tag, uri, libraryUri, e.toString()); | |
| 291 }); | |
| 292 | |
| 293 try { | |
| 294 var msg = [receivePort.sendPort, resourceUri.toString()]; | |
| 295 _loadPort.send(msg); | |
| 296 _startingOneLoadRequest(uri); | |
| 297 } catch (e) { | |
| 298 if (_logBuiltin) { | |
| 299 _print("Exception when communicating with service isolate: $e"); | |
| 300 } | |
| 301 _asyncLoadError(tag, uri, libraryUri, e.toString()); | |
| 302 receivePort.close(); | |
| 272 } | 303 } |
| 273 } | 304 } |
| 274 | 305 |
| 275 | 306 // Returns either a file path or a URI starting with http[s]:, as a String. |
| 276 void _asyncLoadErrorCallback(uri, libraryUri, error) | 307 String _filePathFromUri(String userUri) { |
| 277 native "Builtin_AsyncLoadError"; | |
| 278 | |
| 279 void _asyncLoadError(uri, libraryUri, error) { | |
| 280 assert(_numOutstandingLoadRequests > 0); | |
| 281 if (_logBuiltin) { | |
| 282 _print("_asyncLoadError($uri), error: $error"); | |
| 283 } | |
| 284 _numOutstandingLoadRequests--; | |
| 285 _asyncLoadErrorCallback(uri, libraryUri, error); | |
| 286 if (_numOutstandingLoadRequests == 0) { | |
| 287 _signalDoneLoading(); | |
| 288 _cleanup(); | |
| 289 } | |
| 290 } | |
| 291 | |
| 292 | |
| 293 // Create a Uri of 'userUri'. If the input uri is a package uri, then the | |
| 294 // package uri is resolved. | |
| 295 Uri _createUri(String userUri) { | |
| 296 var uri = Uri.parse(userUri); | 308 var uri = Uri.parse(userUri); |
| 297 if (_logBuiltin) { | 309 if (_logBuiltin) { |
| 298 _print('# Creating uri for: $uri'); | 310 _print('# Getting file path from: $uri'); |
| 299 } | 311 } |
| 300 | 312 |
| 313 var path; | |
| 301 switch (uri.scheme) { | 314 switch (uri.scheme) { |
| 302 case '': | 315 case '': |
| 303 case 'file': | 316 case 'file': |
| 317 return uri.toFilePath(); | |
| 318 case 'package': | |
| 319 return _filePathFromUri(_resolvePackageUri(uri).toString()); | |
| 304 case 'http': | 320 case 'http': |
| 305 case 'https': | 321 case 'https': |
| 306 return uri; | 322 return uri.toString(); |
| 307 case 'package': | |
| 308 return _resolvePackageUri(uri); | |
| 309 default: | 323 default: |
| 310 // Only handling file, http[s], and package URIs | 324 // Only handling file, http, and package URIs |
| 311 // in standalone binary. | 325 // in standalone binary. |
| 312 if (_logBuiltin) { | 326 if (_logBuiltin) { |
| 313 _print('# Unknown scheme (${uri.scheme}) in $uri.'); | 327 _print('# Unknown scheme (${uri.scheme}) in $uri.'); |
| 314 } | 328 } |
| 315 throw 'Not a known scheme: $uri'; | 329 throw 'Not a known scheme: $uri'; |
| 316 } | 330 } |
| 317 } | 331 } |
| 318 | 332 |
| 333 String _operatingSystemName() native "Platform_OperatingSystem"; | |
|
siva
2015/01/22 22:39:31
Platform_OperatingSystem is a native in the IO lib
Cutch
2015/01/26 18:59:30
I've added a new native for builtin that returns t
| |
| 319 | 334 |
| 320 // Asynchronously loads script data through a http[s] or file uri. | 335 String _platformExtensionFileName(String name) { |
| 321 _loadDataAsync(int tag, String uri, String libraryUri) { | 336 var operatingSystemName = _operatingSystemName(); |
| 322 if (tag == null) { | 337 var isLinux = (operatingSystemName == "linux"); |
| 323 uri = _resolveScriptUri(uri); | 338 var isMacOS = (operatingSystemName == "macos"); |
| 324 } | 339 var isWindows = (operatingSystemName == "windows"); |
| 325 Uri resourceUri = _createUri(uri); | 340 var isAndroid = (operatingSystemName == "android"); |
| 326 _numOutstandingLoadRequests++; | 341 |
| 327 if (_logBuiltin) { | 342 if (isLinux || isAndroid) { |
| 328 _print("_loadDataAsync($uri), " | 343 return 'lib$name.so'; |
| 329 "${_numOutstandingLoadRequests} requests outstanding"); | 344 } else if (isMacOS) { |
| 330 } | 345 return 'lib$name.dylib'; |
| 331 if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) { | 346 } else if (isWindows) { |
| 332 _httpGet(resourceUri, libraryUri, (data) { | 347 return '$name.dll'; |
| 333 _loadScript(tag, uri, libraryUri, data); | |
| 334 }); | |
| 335 } else { | 348 } else { |
| 336 var sourceFile = new File(resourceUri.toFilePath()); | 349 if (_logBuiltin) { |
| 337 sourceFile.readAsBytes().then((data) { | 350 _print('Native extensions not supported on $operatingSystemName'); |
| 338 _loadScript(tag, uri, libraryUri, data); | 351 } |
| 339 }, | 352 throw 'Native extensions not supported on $operatingSystemName'; |
| 340 onError: (e) { | |
| 341 _asyncLoadError(uri, libraryUri, e); | |
| 342 }); | |
| 343 } | 353 } |
| 344 } | 354 } |
| 345 | 355 |
| 346 // Returns the directory part, the filename part, and the name | 356 // Returns the directory part, the filename part, and the name |
| 347 // of a native extension URL as a list [directory, filename, name]. | 357 // of a native extension URL as a list [directory, filename, name]. |
| 348 // The directory part is either a file system path or an HTTP(S) URL. | 358 // The directory part is either a file system path or an HTTP(S) URL. |
| 349 // The filename part is the extension name, with the platform-dependent | 359 // The filename part is the extension name, with the platform-dependent |
| 350 // prefixes and extensions added. | 360 // prefixes and extensions added. |
| 351 _extensionPathFromUri(String userUri) { | 361 _extensionPathFromUri(String userUri) { |
| 352 if (!userUri.startsWith(_DART_EXT)) { | 362 if (!userUri.startsWith(_DART_EXT)) { |
| 353 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; | 363 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; |
| 354 } | 364 } |
| 355 userUri = userUri.substring(_DART_EXT.length); | 365 userUri = userUri.substring(_DART_EXT.length); |
| 356 | 366 |
| 357 if (userUri.contains('\\')) { | 367 if (userUri.contains('\\')) { |
| 358 throw 'Unexpected internal error: Extension URI $userUri contains \\'; | 368 throw 'Unexpected internal error: Extension URI $userUri contains \\'; |
| 359 } | 369 } |
| 360 | 370 |
| 361 String filename; | 371 |
| 362 String name; | 372 String name; |
| 363 String path; // Will end in '/'. | 373 String path; // Will end in '/'. |
| 364 int index = userUri.lastIndexOf('/'); | 374 int index = userUri.lastIndexOf('/'); |
| 365 if (index == -1) { | 375 if (index == -1) { |
| 366 name = userUri; | 376 name = userUri; |
| 367 path = './'; | 377 path = './'; |
| 368 } else if (index == userUri.length - 1) { | 378 } else if (index == userUri.length - 1) { |
| 369 throw 'Extension name missing in $extensionUri'; | 379 throw 'Extension name missing in $extensionUri'; |
| 370 } else { | 380 } else { |
| 371 name = userUri.substring(index + 1); | 381 name = userUri.substring(index + 1); |
| 372 path = userUri.substring(0, index + 1); | 382 path = userUri.substring(0, index + 1); |
| 373 } | 383 } |
| 374 | 384 |
| 375 path = _filePathFromUri(path); | 385 path = _filePathFromUri(path); |
| 376 | 386 var filename = _platformExtensionFileName(name); |
| 377 if (Platform.isLinux || Platform.isAndroid) { | |
| 378 filename = 'lib$name.so'; | |
| 379 } else if (Platform.isMacOS) { | |
| 380 filename = 'lib$name.dylib'; | |
| 381 } else if (Platform.isWindows) { | |
| 382 filename = '$name.dll'; | |
| 383 } else { | |
| 384 if (_logBuiltin) { | |
| 385 _print('Native extensions not supported on ${Platform.operatingSystem}'); | |
| 386 } | |
| 387 throw 'Native extensions not supported on ${Platform.operatingSystem}'; | |
| 388 } | |
| 389 | 387 |
| 390 return [path, filename, name]; | 388 return [path, filename, name]; |
| 391 } | 389 } |
| OLD | NEW |