Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: runtime/bin/builtin.dart

Issue 889443002: Service isolate rework take 2 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/builtin.cc ('k') | runtime/bin/builtin_common.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 //////////////////////
12 /* Support for loading within the isolate via dart:io */
13 import 'dart:io';
14
15 // Enable by setting the #define LOAD_VIA_SERVICE_ISOLATE (see dartutils.cc)
16 bool _load_via_service_isolate = false;
17
18 var _httpClient;
19 void _httpGet(int tag,
20 Uri uri,
21 String libraryUri,
22 loadCallback(List<int> data)) {
23 if (_httpClient == null) {
24 _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
25 }
26 _httpClient.getUrl(uri)
27 .then((HttpClientRequest request) => request.close())
28 .then((HttpClientResponse response) {
29 var builder = new BytesBuilder(copy: false);
30 response.listen(
31 builder.add,
32 onDone: () {
33 if (response.statusCode != 200) {
34 var msg = 'Failure getting $uri: '
35 '${response.statusCode} ${response.reasonPhrase}';
36 _asyncLoadError(tag, uri.toString(), libraryUri, msg);
37 }
38 loadCallback(builder.takeBytes());
39 },
40 onError: (error) {
41 _asyncLoadError(tag, uri.toString(), libraryUri, error);
42 });
43 })
44 .catchError((error) {
45 _asyncLoadError(tag, uri.toString(), libraryUri, error);
46 });
47 // TODO(floitsch): remove this line. It's just here to push an event on the
48 // event loop so that we invoke the scheduled microtasks. Also remove the
49 // import of dart:async when this line is not needed anymore.
50 Timer.run(() {});
51 }
52
53
54 void _cleanup() {
55 if (_httpClient != null) {
56 _httpClient.close();
57 _httpClient = null;
58 }
59 }
60
61 _loadDataAsyncDartIO(int tag,
62 String uri,
63 String libraryUri,
64 Uri resourceUri) {
65 _startingOneLoadRequest(uri);
66 if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) {
67 _httpGet(tag, resourceUri, libraryUri, (data) {
68 _loadScript(tag, uri, libraryUri, data);
69 });
70 } else {
71 var sourceFile = new File(resourceUri.toFilePath());
72 sourceFile.readAsBytes().then((data) {
73 _loadScript(tag, uri, libraryUri, data);
74 },
75 onError: (e) {
76 _asyncLoadError(tag, uri, libraryUri, e);
77 });
78 }
79 }
80
81 //////////////////////
82
83 /* See Dart_LibraryTag in dart_api.h */
84 const Dart_kScriptTag = null;
85 const Dart_kImportTag = 0;
86 const Dart_kSourceTag = 1;
87 const Dart_kCanonicalizeUrl = 2;
88
89 // Dart native extension scheme.
90 const _DART_EXT = 'dart-ext:';
91
9 // import 'root_library'; happens here from C Code 92 // import 'root_library'; happens here from C Code
10 93
11 // The root library (aka the script) is imported into this library. The 94 // The root library (aka the script) is imported into this library. The
12 // standalone embedder uses this to lookup the main entrypoint in the 95 // standalone embedder uses this to lookup the main entrypoint in the
13 // root library's namespace. 96 // root library's namespace.
14 Function _getMainClosure() => main; 97 Function _getMainClosure() => main;
15 98
99 // A port for communicating with the service isolate for I/O.
100 SendPort _loadPort;
101
102 const _logBuiltin = false;
16 103
17 // Corelib 'print' implementation. 104 // Corelib 'print' implementation.
18 void _print(arg) { 105 void _print(arg) {
19 _Logger._printString(arg.toString()); 106 _Logger._printString(arg.toString());
20 } 107 }
21 108
22
23 class _Logger { 109 class _Logger {
24 static void _printString(String s) native "Logger_PrintString"; 110 static void _printString(String s) native "Logger_PrintString";
25 } 111 }
26 112
27
28 _getPrintClosure() => _print; 113 _getPrintClosure() => _print;
29 114
30 const _logBuiltin = false; 115 _getCurrentDirectoryPath() native "Directory_Current";
31 116
32 // Corelib 'Uri.base' implementation. 117 // Corelib 'Uri.base' implementation.
33 Uri _uriBase() { 118 Uri _uriBase() {
34 return new Uri.file(Directory.current.path + "/"); 119 return new Uri.file(_getCurrentDirectoryPath() + "/");
35 } 120 }
36 121
37
38 _getUriBaseClosure() => _uriBase; 122 _getUriBaseClosure() => _uriBase;
39 123
40 124
41 // Are we running on Windows? 125 // Are we running on Windows?
42 var _isWindows = false; 126 var _isWindows;
43 var _workingWindowsDrivePrefix; 127 var _workingWindowsDrivePrefix;
44 // The current working directory 128 // The current working directory
45 var _workingDirectoryUri; 129 var _workingDirectoryUri;
46 // The URI that the entry point script was loaded from. Remembered so that 130 // The URI that the entry point script was loaded from. Remembered so that
47 // package imports can be resolved relative to it. 131 // package imports can be resolved relative to it.
48 var _entryPointScript; 132 var _entryPointScript;
49 // The directory to look in to resolve "package:" scheme URIs. 133 // The directory to look in to resolve "package:" scheme URIs.
50 var _packageRoot; 134 var _packageRoot;
51 135
52
53 void _setWindows() {
54 _isWindows = true;
55 }
56
57
58 _sanitizeWindowsPath(path) { 136 _sanitizeWindowsPath(path) {
59 // For Windows we need to massage the paths a bit according to 137 // For Windows we need to massage the paths a bit according to
60 // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx 138 // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
61 // 139 //
62 // Convert 140 // Convert
63 // C:\one\two\three 141 // C:\one\two\three
64 // to 142 // to
65 // /C:/one/two/three 143 // /C:/one/two/three
66 144
67 if (_isWindows == false) { 145 if (_isWindows == false) {
68 // Do nothing when not running Windows. 146 // Do nothing when not running Windows.
69 return path; 147 return path;
70 } 148 }
71 149
72 var fixedPath = "${path.replaceAll('\\', '/')}"; 150 var fixedPath = "${path.replaceAll('\\', '/')}";
73 151
74 if ((path.length > 2) && (path[1] == ':')) { 152 if ((path.length > 2) && (path[1] == ':')) {
75 // Path begins with a drive letter. 153 // Path begins with a drive letter.
76 return '/$fixedPath'; 154 return '/$fixedPath';
77 } 155 }
78 156
79 return fixedPath; 157 return fixedPath;
80 } 158 }
81 159
160 _trimWindowsPath(path) {
161 // Convert /X:/ to X:/.
162 if (_isWindows == false) {
163 // Do nothing when not running Windows.
164 return path;
165 }
166 if (!path.startsWith('/') || (path.length < 3)) {
167 return path;
168 }
169 // Match '/?:'.
170 if ((path[0] == '/') && (path[2] == ':')) {
171 // Remove leading '/'.
172 return path.substring(1);
173 }
174 return path;
175 }
82 176
83 _enforceTrailingSlash(uri) { 177 _enforceTrailingSlash(uri) {
84 // Ensure we have a trailing slash character. 178 // Ensure we have a trailing slash character.
85 if (!uri.endsWith('/')) { 179 if (!uri.endsWith('/')) {
86 return '$uri/'; 180 return '$uri/';
87 } 181 }
88 return uri; 182 return uri;
89 } 183 }
90 184
91 185
(...skipping 19 matching lines...) Expand all
111 } 205 }
112 206
113 207
114 _setPackageRoot(String packageRoot) { 208 _setPackageRoot(String packageRoot) {
115 packageRoot = _enforceTrailingSlash(packageRoot); 209 packageRoot = _enforceTrailingSlash(packageRoot);
116 if (packageRoot.startsWith('file:') || 210 if (packageRoot.startsWith('file:') ||
117 packageRoot.startsWith('http:') || 211 packageRoot.startsWith('http:') ||
118 packageRoot.startsWith('https:')) { 212 packageRoot.startsWith('https:')) {
119 _packageRoot = _workingDirectoryUri.resolve(packageRoot); 213 _packageRoot = _workingDirectoryUri.resolve(packageRoot);
120 } else { 214 } else {
215 packageRoot = _sanitizeWindowsPath(packageRoot);
216 packageRoot = _trimWindowsPath(packageRoot);
121 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); 217 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot));
122 } 218 }
123 if (_logBuiltin) { 219 if (_logBuiltin) {
124 _print('# Package root: $packageRoot -> $_packageRoot'); 220 _print('# Package root: $packageRoot -> $_packageRoot');
125 } 221 }
126 } 222 }
127 223
128 224
225 // Given a uri with a 'package' scheme, return a Uri that is prefixed with
226 // the package root.
227 Uri _resolvePackageUri(Uri uri) {
228 if (!uri.host.isEmpty) {
229 var path = '${uri.host}${uri.path}';
230 var right = 'package:$path';
231 var wrong = 'package://$path';
232
233 throw "URIs using the 'package:' scheme should look like "
234 "'$right', not '$wrong'.";
235 }
236
237 var packageRoot = _packageRoot == null ?
238 _entryPointScript.resolve('packages/') :
239 _packageRoot;
240 return packageRoot.resolve(uri.path);
241 }
242
243
244
129 String _resolveScriptUri(String scriptName) { 245 String _resolveScriptUri(String scriptName) {
130 if (_workingDirectoryUri == null) { 246 if (_workingDirectoryUri == null) {
131 throw 'No current working directory set.'; 247 throw 'No current working directory set.';
132 } 248 }
133 scriptName = _sanitizeWindowsPath(scriptName); 249 scriptName = _sanitizeWindowsPath(scriptName);
134 250
135 var scriptUri = Uri.parse(scriptName); 251 var scriptUri = Uri.parse(scriptName);
136 if (scriptUri.scheme != '') { 252 if (scriptUri.scheme != '') {
137 // Script has a scheme, assume that it is fully formed. 253 // Script has a scheme, assume that it is fully formed.
138 _entryPointScript = scriptUri; 254 _entryPointScript = scriptUri;
139 } else { 255 } else {
140 // Script does not have a scheme, assume that it is a path, 256 // Script does not have a scheme, assume that it is a path,
141 // resolve it against the working directory. 257 // resolve it against the working directory.
142 _entryPointScript = _workingDirectoryUri.resolve(scriptName); 258 _entryPointScript = _workingDirectoryUri.resolve(scriptName);
143 } 259 }
144 if (_logBuiltin) { 260 if (_logBuiltin) {
145 _print('# Resolved entry point to: $_entryPointScript'); 261 _print('# Resolved entry point to: $_entryPointScript');
146 } 262 }
147 return _entryPointScript.toString(); 263 return _entryPointScript.toString();
148 } 264 }
149 265
150 const _DART_EXT = 'dart-ext:';
151 266
267 // Function called by standalone embedder to resolve uris.
152 String _resolveUri(String base, String userString) { 268 String _resolveUri(String base, String userString) {
153 if (_logBuiltin) { 269 if (_logBuiltin) {
154 _print('# Resolving: $userString from $base'); 270 _print('# Resolving: $userString from $base');
155 } 271 }
156 var baseUri = Uri.parse(base); 272 var baseUri = Uri.parse(base);
157 if (userString.startsWith(_DART_EXT)) { 273 if (userString.startsWith(_DART_EXT)) {
158 var uri = userString.substring(_DART_EXT.length); 274 var uri = userString.substring(_DART_EXT.length);
159 return '$_DART_EXT${baseUri.resolve(uri)}'; 275 return '$_DART_EXT${baseUri.resolve(uri)}';
160 } else { 276 } else {
161 return baseUri.resolve(userString).toString(); 277 return baseUri.resolve(userString).toString();
162 } 278 }
163 } 279 }
164 280
165 281 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); 282 var uri = Uri.parse(userUri);
169 if (_logBuiltin) {
170 _print('# Getting file path from: $uri');
171 }
172
173 var path;
174 switch (uri.scheme) { 283 switch (uri.scheme) {
175 case '': 284 case '':
176 case 'file': 285 case 'file':
177 return uri.toFilePath();
178 case 'package':
179 return _filePathFromUri(_resolvePackageUri(uri).toString());
180 case 'http': 286 case 'http':
181 case 'https': 287 case 'https':
182 return uri.toString(); 288 return uri;
289 case 'package':
290 return _resolvePackageUri(uri);
183 default: 291 default:
184 // Only handling file, http, and package URIs 292 // Only handling file, http[s], and package URIs
185 // in standalone binary. 293 // in standalone binary.
186 if (_logBuiltin) { 294 if (_logBuiltin) {
187 _print('# Unknown scheme (${uri.scheme}) in $uri.'); 295 _print('# Unknown scheme (${uri.scheme}) in $uri.');
188 } 296 }
189 throw 'Not a known scheme: $uri'; 297 throw 'Not a known scheme: $uri';
190 } 298 }
191 } 299 }
192 300
193
194 Uri _resolvePackageUri(Uri uri) {
195 if (!uri.host.isEmpty) {
196 var path = '${uri.host}${uri.path}';
197 var right = 'package:$path';
198 var wrong = 'package://$path';
199
200 throw "URIs using the 'package:' scheme should look like "
201 "'$right', not '$wrong'.";
202 }
203
204 var packageRoot = _packageRoot == null ?
205 _entryPointScript.resolve('packages/') :
206 _packageRoot;
207 return packageRoot.resolve(uri.path);
208 }
209
210
211 int _numOutstandingLoadRequests = 0; 301 int _numOutstandingLoadRequests = 0;
212 var _httpClient; 302 void _finishedOneLoadRequest(String uri) {
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 }
253 }
254
255 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data)
256 native "Builtin_LoadScript";
257
258 void _loadScript(int tag, String uri, String libraryUri, List<int> data) {
259 // TODO: Currently a compilation error while loading the script is
260 // fatal for the isolate. _loadScriptCallback() does not return and
261 // the _numOutstandingLoadRequests counter remains out of sync.
262 _loadScriptCallback(tag, uri, libraryUri, data);
263 assert(_numOutstandingLoadRequests > 0); 303 assert(_numOutstandingLoadRequests > 0);
264 _numOutstandingLoadRequests--; 304 _numOutstandingLoadRequests--;
265 if (_logBuiltin) { 305 if (_logBuiltin) {
266 _print("native Builtin_LoadScript($uri) completed, " 306 _print("Loading of $uri finished, "
267 "${_numOutstandingLoadRequests} requests remaining"); 307 "${_numOutstandingLoadRequests} requests remaining");
268 } 308 }
269 if (_numOutstandingLoadRequests == 0) { 309 if (_numOutstandingLoadRequests == 0) {
270 _signalDoneLoading(); 310 _signalDoneLoading();
271 _cleanup(); 311 _cleanup();
272 } 312 }
273 } 313 }
274 314
315 void _startingOneLoadRequest(String uri) {
316 assert(_numOutstandingLoadRequests >= 0);
317 _numOutstandingLoadRequests++;
318 if (_logBuiltin) {
319 _print("Loading of $uri started, "
320 "${_numOutstandingLoadRequests} requests outstanding");
321 }
322 }
275 323
324 class LoadError extends Error {
325 final String message;
326 LoadError(this.message);
327
328 String toString() => 'Load Error: $message';
329 }
330
331 void _signalDoneLoading() native "Builtin_DoneLoading";
332 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data)
333 native "Builtin_LoadScript";
276 void _asyncLoadErrorCallback(uri, libraryUri, error) 334 void _asyncLoadErrorCallback(uri, libraryUri, error)
277 native "Builtin_AsyncLoadError"; 335 native "Builtin_AsyncLoadError";
278 336
279 void _asyncLoadError(uri, libraryUri, error) { 337 void _loadScript(int tag, String uri, String libraryUri, List<int> data) {
280 assert(_numOutstandingLoadRequests > 0); 338 // TODO: Currently a compilation error while loading the script is
339 // fatal for the isolate. _loadScriptCallback() does not return and
340 // the _numOutstandingLoadRequests counter remains out of sync.
341 _loadScriptCallback(tag, uri, libraryUri, data);
342 _finishedOneLoadRequest(uri);
343 }
344
345 void _asyncLoadError(tag, uri, libraryUri, error) {
281 if (_logBuiltin) { 346 if (_logBuiltin) {
282 _print("_asyncLoadError($uri), error: $error"); 347 _print("_asyncLoadError($uri), error: $error");
283 } 348 }
284 _numOutstandingLoadRequests--; 349 if (tag == Dart_kImportTag) {
285 _asyncLoadErrorCallback(uri, libraryUri, error); 350 // When importing a library, the libraryUri is the imported
286 if (_numOutstandingLoadRequests == 0) { 351 // uri.
287 _signalDoneLoading(); 352 libraryUri = uri;
288 _cleanup(); 353 }
354 _asyncLoadErrorCallback(uri, libraryUri, new LoadError(error));
355 _finishedOneLoadRequest(uri);
356 }
357
358
359 _loadDataAsyncLoadPort(int tag,
360 String uri,
361 String libraryUri,
362 Uri resourceUri) {
363 var receivePort = new ReceivePort();
364 receivePort.first.then((dataOrError) {
365 if (dataOrError is List<int>) {
366 _loadScript(tag, uri, libraryUri, dataOrError);
367 } else {
368 _asyncLoadError(tag, uri, libraryUri, dataOrError);
369 }
370 }).catchError((e) {
371 _asyncLoadError(tag, uri, libraryUri, e.toString());
372 });
373
374 try {
375 var msg = [receivePort.sendPort, resourceUri.toString()];
376 _loadPort.send(msg);
377 _startingOneLoadRequest(uri);
378 } catch (e) {
379 if (_logBuiltin) {
380 _print("Exception when communicating with service isolate: $e");
381 }
382 _asyncLoadError(tag, uri, libraryUri, e.toString());
383 receivePort.close();
289 } 384 }
290 } 385 }
291 386
387 // Asynchronously loads script data through a http[s] or file uri.
388 _loadDataAsync(int tag, String uri, String libraryUri) {
389 if (tag == Dart_kScriptTag) {
390 uri = _resolveScriptUri(uri);
391 }
292 392
293 // Create a Uri of 'userUri'. If the input uri is a package uri, then the 393 Uri resourceUri = _createUri(uri);
294 // package uri is resolved. 394
295 Uri _createUri(String userUri) { 395 if (_load_via_service_isolate) {
396 _loadDataAsyncLoadPort(tag, uri, libraryUri, resourceUri);
397 } else {
398 _loadDataAsyncDartIO(tag, uri, libraryUri, resourceUri);
399 }
400
401 }
402
403 // Returns either a file path or a URI starting with http[s]:, as a String.
404 String _filePathFromUri(String userUri) {
296 var uri = Uri.parse(userUri); 405 var uri = Uri.parse(userUri);
297 if (_logBuiltin) { 406 if (_logBuiltin) {
298 _print('# Creating uri for: $uri'); 407 _print('# Getting file path from: $uri');
299 } 408 }
300 409
410 var path;
301 switch (uri.scheme) { 411 switch (uri.scheme) {
302 case '': 412 case '':
303 case 'file': 413 case 'file':
414 return uri.toFilePath();
415 case 'package':
416 return _filePathFromUri(_resolvePackageUri(uri).toString());
304 case 'http': 417 case 'http':
305 case 'https': 418 case 'https':
306 return uri; 419 return uri.toString();
307 case 'package':
308 return _resolvePackageUri(uri);
309 default: 420 default:
310 // Only handling file, http[s], and package URIs 421 // Only handling file, http, and package URIs
311 // in standalone binary. 422 // in standalone binary.
312 if (_logBuiltin) { 423 if (_logBuiltin) {
313 _print('# Unknown scheme (${uri.scheme}) in $uri.'); 424 _print('# Unknown scheme (${uri.scheme}) in $uri.');
314 } 425 }
315 throw 'Not a known scheme: $uri'; 426 throw 'Not a known scheme: $uri';
316 } 427 }
317 } 428 }
318 429
430 String _nativeLibraryExtension() native "Builtin_NativeLibraryExtension";
319 431
320 // Asynchronously loads script data through a http[s] or file uri. 432 String _platformExtensionFileName(String name) {
321 _loadDataAsync(int tag, String uri, String libraryUri) { 433 var extension = _nativeLibraryExtension();
322 if (tag == null) { 434
323 uri = _resolveScriptUri(uri); 435 if (_isWindows) {
324 } 436 return '$name.$extension';
325 Uri resourceUri = _createUri(uri);
326 _numOutstandingLoadRequests++;
327 if (_logBuiltin) {
328 _print("_loadDataAsync($uri), "
329 "${_numOutstandingLoadRequests} requests outstanding");
330 }
331 if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) {
332 _httpGet(resourceUri, libraryUri, (data) {
333 _loadScript(tag, uri, libraryUri, data);
334 });
335 } else { 437 } else {
336 var sourceFile = new File(resourceUri.toFilePath()); 438 return 'lib$name.$extension';
337 sourceFile.readAsBytes().then((data) {
338 _loadScript(tag, uri, libraryUri, data);
339 },
340 onError: (e) {
341 _asyncLoadError(uri, libraryUri, e);
342 });
343 } 439 }
344 } 440 }
345 441
346 // Returns the directory part, the filename part, and the name 442 // Returns the directory part, the filename part, and the name
347 // of a native extension URL as a list [directory, filename, name]. 443 // 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. 444 // 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 445 // The filename part is the extension name, with the platform-dependent
350 // prefixes and extensions added. 446 // prefixes and extensions added.
351 _extensionPathFromUri(String userUri) { 447 _extensionPathFromUri(String userUri) {
352 if (!userUri.startsWith(_DART_EXT)) { 448 if (!userUri.startsWith(_DART_EXT)) {
353 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; 449 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:';
354 } 450 }
355 userUri = userUri.substring(_DART_EXT.length); 451 userUri = userUri.substring(_DART_EXT.length);
356 452
357 if (userUri.contains('\\')) { 453 if (userUri.contains('\\')) {
358 throw 'Unexpected internal error: Extension URI $userUri contains \\'; 454 throw 'Unexpected internal error: Extension URI $userUri contains \\';
359 } 455 }
360 456
361 String filename; 457
362 String name; 458 String name;
363 String path; // Will end in '/'. 459 String path; // Will end in '/'.
364 int index = userUri.lastIndexOf('/'); 460 int index = userUri.lastIndexOf('/');
365 if (index == -1) { 461 if (index == -1) {
366 name = userUri; 462 name = userUri;
367 path = './'; 463 path = './';
368 } else if (index == userUri.length - 1) { 464 } else if (index == userUri.length - 1) {
369 throw 'Extension name missing in $extensionUri'; 465 throw 'Extension name missing in $extensionUri';
370 } else { 466 } else {
371 name = userUri.substring(index + 1); 467 name = userUri.substring(index + 1);
372 path = userUri.substring(0, index + 1); 468 path = userUri.substring(0, index + 1);
373 } 469 }
374 470
375 path = _filePathFromUri(path); 471 path = _filePathFromUri(path);
376 472 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 473
390 return [path, filename, name]; 474 return [path, filename, name];
391 } 475 }
OLDNEW
« no previous file with comments | « runtime/bin/builtin.cc ('k') | runtime/bin/builtin_common.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698