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

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

Issue 867113003: Revert r43217, r43215, r43208, r43207, and r43202. (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';
6 import 'dart:async'; 7 import 'dart:async';
7 import 'dart:convert'; 8 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
20 // import 'root_library'; happens here from C Code 9 // import 'root_library'; happens here from C Code
21 10
22 // The root library (aka the script) is imported into this library. The 11 // The root library (aka the script) is imported into this library. The
23 // standalone embedder uses this to lookup the main entrypoint in the 12 // standalone embedder uses this to lookup the main entrypoint in the
24 // root library's namespace. 13 // root library's namespace.
25 Function _getMainClosure() => main; 14 Function _getMainClosure() => main;
26 15
27 // A port for communicating with the service isolate for I/O.
28 SendPort _loadPort;
29
30 const _logBuiltin = false;
31 16
32 // Corelib 'print' implementation. 17 // Corelib 'print' implementation.
33 void _print(arg) { 18 void _print(arg) {
34 _Logger._printString(arg.toString()); 19 _Logger._printString(arg.toString());
35 } 20 }
36 21
22
37 class _Logger { 23 class _Logger {
38 static void _printString(String s) native "Logger_PrintString"; 24 static void _printString(String s) native "Logger_PrintString";
39 } 25 }
40 26
27
41 _getPrintClosure() => _print; 28 _getPrintClosure() => _print;
42 29
43 _getCurrentDirectoryPath() native "Directory_Current"; 30 const _logBuiltin = false;
44 31
45 // Corelib 'Uri.base' implementation. 32 // Corelib 'Uri.base' implementation.
46 Uri _uriBase() { 33 Uri _uriBase() {
47 return new Uri.file(_getCurrentDirectoryPath() + "/"); 34 return new Uri.file(Directory.current.path + "/");
48 } 35 }
49 36
37
50 _getUriBaseClosure() => _uriBase; 38 _getUriBaseClosure() => _uriBase;
51 39
52 40
53 // Are we running on Windows? 41 // Are we running on Windows?
54 var _isWindows = false; 42 var _isWindows = false;
55 var _workingWindowsDrivePrefix; 43 var _workingWindowsDrivePrefix;
56 // The current working directory 44 // The current working directory
57 var _workingDirectoryUri; 45 var _workingDirectoryUri;
58 // The URI that the entry point script was loaded from. Remembered so that 46 // The URI that the entry point script was loaded from. Remembered so that
59 // package imports can be resolved relative to it. 47 // package imports can be resolved relative to it.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 _packageRoot = _workingDirectoryUri.resolve(packageRoot); 119 _packageRoot = _workingDirectoryUri.resolve(packageRoot);
132 } else { 120 } else {
133 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); 121 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot));
134 } 122 }
135 if (_logBuiltin) { 123 if (_logBuiltin) {
136 _print('# Package root: $packageRoot -> $_packageRoot'); 124 _print('# Package root: $packageRoot -> $_packageRoot');
137 } 125 }
138 } 126 }
139 127
140 128
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
161 String _resolveScriptUri(String scriptName) { 129 String _resolveScriptUri(String scriptName) {
162 if (_workingDirectoryUri == null) { 130 if (_workingDirectoryUri == null) {
163 throw 'No current working directory set.'; 131 throw 'No current working directory set.';
164 } 132 }
165 scriptName = _sanitizeWindowsPath(scriptName); 133 scriptName = _sanitizeWindowsPath(scriptName);
166 134
167 var scriptUri = Uri.parse(scriptName); 135 var scriptUri = Uri.parse(scriptName);
168 if (scriptUri.scheme != '') { 136 if (scriptUri.scheme != '') {
169 // Script has a scheme, assume that it is fully formed. 137 // Script has a scheme, assume that it is fully formed.
170 _entryPointScript = scriptUri; 138 _entryPointScript = scriptUri;
171 } else { 139 } else {
172 // Script does not have a scheme, assume that it is a path, 140 // Script does not have a scheme, assume that it is a path,
173 // resolve it against the working directory. 141 // resolve it against the working directory.
174 _entryPointScript = _workingDirectoryUri.resolve(scriptName); 142 _entryPointScript = _workingDirectoryUri.resolve(scriptName);
175 } 143 }
176 if (_logBuiltin) { 144 if (_logBuiltin) {
177 _print('# Resolved entry point to: $_entryPointScript'); 145 _print('# Resolved entry point to: $_entryPointScript');
178 } 146 }
179 return _entryPointScript.toString(); 147 return _entryPointScript.toString();
180 } 148 }
181 149
150 const _DART_EXT = 'dart-ext:';
182 151
183 // Function called by standalone embedder to resolve uris.
184 String _resolveUri(String base, String userString) { 152 String _resolveUri(String base, String userString) {
185 if (_logBuiltin) { 153 if (_logBuiltin) {
186 _print('# Resolving: $userString from $base'); 154 _print('# Resolving: $userString from $base');
187 } 155 }
188 var baseUri = Uri.parse(base); 156 var baseUri = Uri.parse(base);
189 if (userString.startsWith(_DART_EXT)) { 157 if (userString.startsWith(_DART_EXT)) {
190 var uri = userString.substring(_DART_EXT.length); 158 var uri = userString.substring(_DART_EXT.length);
191 return '$_DART_EXT${baseUri.resolve(uri)}'; 159 return '$_DART_EXT${baseUri.resolve(uri)}';
192 } else { 160 } else {
193 return baseUri.resolve(userString).toString(); 161 return baseUri.resolve(userString).toString();
194 } 162 }
195 } 163 }
196 164
197 Uri _createUri(String userUri) { 165
166 // Returns either a file path or a URI starting with http[s]:, as a String.
167 String _filePathFromUri(String userUri) {
198 var uri = Uri.parse(userUri); 168 var uri = Uri.parse(userUri);
169 if (_logBuiltin) {
170 _print('# Getting file path from: $uri');
171 }
172
173 var path;
199 switch (uri.scheme) { 174 switch (uri.scheme) {
200 case '': 175 case '':
201 case 'file': 176 case 'file':
177 return uri.toFilePath();
178 case 'package':
179 return _filePathFromUri(_resolvePackageUri(uri).toString());
202 case 'http': 180 case 'http':
203 case 'https': 181 case 'https':
204 return uri; 182 return uri.toString();
205 case 'package':
206 return _resolvePackageUri(uri);
207 default: 183 default:
208 // Only handling file, http[s], and package URIs 184 // Only handling file, http, and package URIs
209 // in standalone binary. 185 // in standalone binary.
210 if (_logBuiltin) { 186 if (_logBuiltin) {
211 _print('# Unknown scheme (${uri.scheme}) in $uri.'); 187 _print('# Unknown scheme (${uri.scheme}) in $uri.');
212 } 188 }
213 throw 'Not a known scheme: $uri'; 189 throw 'Not a known scheme: $uri';
214 } 190 }
215 } 191 }
216 192
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
217 int _numOutstandingLoadRequests = 0; 211 int _numOutstandingLoadRequests = 0;
218 void _finishedOneLoadRequest(String uri) { 212 var _httpClient;
219 assert(_numOutstandingLoadRequests > 0); 213
220 _numOutstandingLoadRequests--; 214 void _httpGet(Uri uri, String libraryUri, loadCallback(List<int> data)) {
221 if (_logBuiltin) { 215 if (_httpClient == null) {
222 _print("Loading of $uri finished, " 216 _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
223 "${_numOutstandingLoadRequests} requests remaining");
224 } 217 }
225 if (_numOutstandingLoadRequests == 0) { 218 _httpClient.getUrl(uri)
226 _signalDoneLoading(); 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;
227 } 252 }
228 } 253 }
229 254
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";
247 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data) 255 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data)
248 native "Builtin_LoadScript"; 256 native "Builtin_LoadScript";
249 void _asyncLoadErrorCallback(uri, libraryUri, error)
250 native "Builtin_AsyncLoadError";
251 257
252 void _loadScript(int tag, String uri, String libraryUri, List<int> data) { 258 void _loadScript(int tag, String uri, String libraryUri, List<int> data) {
253 // TODO: Currently a compilation error while loading the script is 259 // TODO: Currently a compilation error while loading the script is
254 // fatal for the isolate. _loadScriptCallback() does not return and 260 // fatal for the isolate. _loadScriptCallback() does not return and
255 // the _numOutstandingLoadRequests counter remains out of sync. 261 // the _numOutstandingLoadRequests counter remains out of sync.
256 _loadScriptCallback(tag, uri, libraryUri, data); 262 _loadScriptCallback(tag, uri, libraryUri, data);
257 _finishedOneLoadRequest(uri); 263 assert(_numOutstandingLoadRequests > 0);
264 _numOutstandingLoadRequests--;
265 if (_logBuiltin) {
266 _print("native Builtin_LoadScript($uri) completed, "
267 "${_numOutstandingLoadRequests} requests remaining");
268 }
269 if (_numOutstandingLoadRequests == 0) {
270 _signalDoneLoading();
271 _cleanup();
272 }
258 } 273 }
259 274
260 void _asyncLoadError(tag, uri, libraryUri, error) { 275
276 void _asyncLoadErrorCallback(uri, libraryUri, error)
277 native "Builtin_AsyncLoadError";
278
279 void _asyncLoadError(uri, libraryUri, error) {
280 assert(_numOutstandingLoadRequests > 0);
261 if (_logBuiltin) { 281 if (_logBuiltin) {
262 _print("_asyncLoadError($uri), error: $error"); 282 _print("_asyncLoadError($uri), error: $error");
263 } 283 }
264 if (tag == Dart_kImportTag) { 284 _numOutstandingLoadRequests--;
265 // When importing a library, the libraryUri is the imported 285 _asyncLoadErrorCallback(uri, libraryUri, error);
266 // uri. 286 if (_numOutstandingLoadRequests == 0) {
267 libraryUri = uri; 287 _signalDoneLoading();
288 _cleanup();
268 } 289 }
269 _asyncLoadErrorCallback(uri, libraryUri, new LoadError(error));
270 _finishedOneLoadRequest(uri);
271 } 290 }
272 291
273 292
274 // Asynchronously loads script data through a http[s] or file uri. 293 // Create a Uri of 'userUri'. If the input uri is a package uri, then the
275 _loadDataAsync(int tag, String uri, String libraryUri) { 294 // package uri is resolved.
276 if (tag == Dart_kScriptTag) { 295 Uri _createUri(String userUri) {
277 uri = _resolveScriptUri(uri); 296 var uri = Uri.parse(userUri);
297 if (_logBuiltin) {
298 _print('# Creating uri for: $uri');
278 } 299 }
279 300
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();
303 }
304 }
305
306 // Returns either a file path or a URI starting with http[s]:, as a String.
307 String _filePathFromUri(String userUri) {
308 var uri = Uri.parse(userUri);
309 if (_logBuiltin) {
310 _print('# Getting file path from: $uri');
311 }
312
313 var path;
314 switch (uri.scheme) { 301 switch (uri.scheme) {
315 case '': 302 case '':
316 case 'file': 303 case 'file':
317 return uri.toFilePath();
318 case 'package':
319 return _filePathFromUri(_resolvePackageUri(uri).toString());
320 case 'http': 304 case 'http':
321 case 'https': 305 case 'https':
322 return uri.toString(); 306 return uri;
307 case 'package':
308 return _resolvePackageUri(uri);
323 default: 309 default:
324 // Only handling file, http, and package URIs 310 // Only handling file, http[s], and package URIs
325 // in standalone binary. 311 // in standalone binary.
326 if (_logBuiltin) { 312 if (_logBuiltin) {
327 _print('# Unknown scheme (${uri.scheme}) in $uri.'); 313 _print('# Unknown scheme (${uri.scheme}) in $uri.');
328 } 314 }
329 throw 'Not a known scheme: $uri'; 315 throw 'Not a known scheme: $uri';
330 } 316 }
331 } 317 }
332 318
333 String _nativeLibraryExtension() native "Builtin_NativeLibraryExtension";
334 319
335 String _platformExtensionFileName(String name) { 320 // Asynchronously loads script data through a http[s] or file uri.
336 var extension = _nativeLibraryExtension(); 321 _loadDataAsync(int tag, String uri, String libraryUri) {
337 322 if (tag == null) {
338 if (_isWindows) { 323 uri = _resolveScriptUri(uri);
339 return '$name.$extension'; 324 }
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 });
340 } else { 335 } else {
341 return 'lib$name.$extension'; 336 var sourceFile = new File(resourceUri.toFilePath());
337 sourceFile.readAsBytes().then((data) {
338 _loadScript(tag, uri, libraryUri, data);
339 },
340 onError: (e) {
341 _asyncLoadError(uri, libraryUri, e);
342 });
342 } 343 }
343 } 344 }
344 345
345 // Returns the directory part, the filename part, and the name 346 // Returns the directory part, the filename part, and the name
346 // of a native extension URL as a list [directory, filename, name]. 347 // of a native extension URL as a list [directory, filename, name].
347 // The directory part is either a file system path or an HTTP(S) URL. 348 // The directory part is either a file system path or an HTTP(S) URL.
348 // The filename part is the extension name, with the platform-dependent 349 // The filename part is the extension name, with the platform-dependent
349 // prefixes and extensions added. 350 // prefixes and extensions added.
350 _extensionPathFromUri(String userUri) { 351 _extensionPathFromUri(String userUri) {
351 if (!userUri.startsWith(_DART_EXT)) { 352 if (!userUri.startsWith(_DART_EXT)) {
352 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:'; 353 throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:';
353 } 354 }
354 userUri = userUri.substring(_DART_EXT.length); 355 userUri = userUri.substring(_DART_EXT.length);
355 356
356 if (userUri.contains('\\')) { 357 if (userUri.contains('\\')) {
357 throw 'Unexpected internal error: Extension URI $userUri contains \\'; 358 throw 'Unexpected internal error: Extension URI $userUri contains \\';
358 } 359 }
359 360
360 361 String filename;
361 String name; 362 String name;
362 String path; // Will end in '/'. 363 String path; // Will end in '/'.
363 int index = userUri.lastIndexOf('/'); 364 int index = userUri.lastIndexOf('/');
364 if (index == -1) { 365 if (index == -1) {
365 name = userUri; 366 name = userUri;
366 path = './'; 367 path = './';
367 } else if (index == userUri.length - 1) { 368 } else if (index == userUri.length - 1) {
368 throw 'Extension name missing in $extensionUri'; 369 throw 'Extension name missing in $extensionUri';
369 } else { 370 } else {
370 name = userUri.substring(index + 1); 371 name = userUri.substring(index + 1);
371 path = userUri.substring(0, index + 1); 372 path = userUri.substring(0, index + 1);
372 } 373 }
373 374
374 path = _filePathFromUri(path); 375 path = _filePathFromUri(path);
375 var filename = _platformExtensionFileName(name); 376
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 }
376 389
377 return [path, filename, name]; 390 return [path, filename, name];
378 } 391 }
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