| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 library mojo_builtin; | 5 library mojo_builtin; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 //import 'dart:_internal'; | 9 //import 'dart:_internal'; |
| 10 import 'dart:mojo.core'; | 10 import 'dart:mojo.internal'; |
| 11 // import 'root_library'; happens here from C Code | 11 // import 'root_library'; happens here from C Code |
| 12 | 12 |
| 13 // The root library (aka the script) is imported into this library. The | 13 // The root library (aka the script) is imported into this library. The |
| 14 // embedder uses this to lookup the main entrypoint in the root library's | 14 // embedder uses this to lookup the main entrypoint in the root library's |
| 15 // namespace. | 15 // namespace. |
| 16 Function _getMainClosure() => main; | 16 Function _getMainClosure() => main; |
| 17 | 17 |
| 18 | |
| 19 // Corelib 'print' implementation. | 18 // Corelib 'print' implementation. |
| 20 void _print(arg) { | 19 void _print(arg) { |
| 21 _Logger._printString(arg.toString()); | 20 _Logger._printString(arg.toString()); |
| 22 } | 21 } |
| 23 | 22 |
| 24 | |
| 25 class _Logger { | 23 class _Logger { |
| 26 static void _printString(String s) native "Logger_PrintString"; | 24 static void _printString(String s) native "Logger_PrintString"; |
| 27 } | 25 } |
| 28 | 26 |
| 29 | |
| 30 _getPrintClosure() => _print; | 27 _getPrintClosure() => _print; |
| 31 | 28 |
| 32 const _logBuiltin = false; | 29 const _logBuiltin = false; |
| 33 | 30 |
| 34 | |
| 35 Uri _uriBase() { | 31 Uri _uriBase() { |
| 36 return _entryPointScript.resolve('.'); | 32 return _entryPointScript.resolve('.'); |
| 37 } | 33 } |
| 38 _getUriBaseClosure() => _uriBase; | 34 _getUriBaseClosure() => _uriBase; |
| 39 | 35 |
| 40 // The current working directory | 36 // The current working directory |
| 41 var _workingDirectoryUri; | 37 var _workingDirectoryUri; |
| 42 // The URI that the entry point script was loaded from. Remembered so that | 38 // The URI that the entry point script was loaded from. Remembered so that |
| 43 // package imports can be resolved relative to it. | 39 // package imports can be resolved relative to it. |
| 44 var _entryPointScript; | 40 var _entryPointScript; |
| 45 // The directory to look in to resolve "package:" scheme URIs. | 41 // The directory to look in to resolve "package:" scheme URIs. |
| 46 var _packageRoot; | 42 var _packageRoot; |
| 47 | 43 |
| 48 _setupHooks() { | 44 _setupHooks() { |
| 49 VMLibraryHooks.eventHandlerSendData = MojoHandleWatcher.timer; | 45 VMLibraryHooks.eventHandlerSendData = MojoHandleWatcher.timer; |
| 50 } | 46 } |
| 51 | 47 |
| 52 | |
| 53 _enforceTrailingSlash(uri) { | 48 _enforceTrailingSlash(uri) { |
| 54 // Ensure we have a trailing slash character. | 49 // Ensure we have a trailing slash character. |
| 55 if (!uri.endsWith('/')) { | 50 if (!uri.endsWith('/')) { |
| 56 return '$uri/'; | 51 return '$uri/'; |
| 57 } | 52 } |
| 58 return uri; | 53 return uri; |
| 59 } | 54 } |
| 60 | 55 |
| 61 | |
| 62 void _setWorkingDirectory(cwd) { | 56 void _setWorkingDirectory(cwd) { |
| 63 cwd = _enforceTrailingSlash(cwd); | 57 cwd = _enforceTrailingSlash(cwd); |
| 64 _workingDirectoryUri = new Uri(scheme: 'file', path: cwd); | 58 _workingDirectoryUri = new Uri(scheme: 'file', path: cwd); |
| 65 if (_logBuiltin) { | 59 if (_logBuiltin) { |
| 66 _print('# Working Directory: $cwd'); | 60 _print('# Working Directory: $cwd'); |
| 67 } | 61 } |
| 68 } | 62 } |
| 69 | 63 |
| 70 | |
| 71 _setPackageRoot(String packageRoot) { | 64 _setPackageRoot(String packageRoot) { |
| 72 packageRoot = _enforceTrailingSlash(packageRoot); | 65 packageRoot = _enforceTrailingSlash(packageRoot); |
| 73 if (packageRoot.startsWith('file:') || | 66 if (packageRoot.startsWith('file:') || |
| 74 packageRoot.startsWith('http:') || | 67 packageRoot.startsWith('http:') || |
| 75 packageRoot.startsWith('https:')) { | 68 packageRoot.startsWith('https:')) { |
| 76 _packageRoot = _workingDirectoryUri.resolve(packageRoot); | 69 _packageRoot = _workingDirectoryUri.resolve(packageRoot); |
| 77 } else { | 70 } else { |
| 78 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); | 71 _packageRoot = _workingDirectoryUri.resolveUri(new Uri.file(packageRoot)); |
| 79 } | 72 } |
| 80 if (_logBuiltin) { | 73 if (_logBuiltin) { |
| 81 _print('# Package root: $packageRoot -> $_packageRoot'); | 74 _print('# Package root: $packageRoot -> $_packageRoot'); |
| 82 } | 75 } |
| 83 } | 76 } |
| 84 | 77 |
| 85 | |
| 86 String _resolveScriptUri(String scriptName) { | 78 String _resolveScriptUri(String scriptName) { |
| 87 if (_workingDirectoryUri == null) { | 79 if (_workingDirectoryUri == null) { |
| 88 throw 'No current working directory set.'; | 80 throw 'No current working directory set.'; |
| 89 } | 81 } |
| 90 | 82 |
| 91 var scriptUri = Uri.parse(scriptName); | 83 var scriptUri = Uri.parse(scriptName); |
| 92 if (scriptUri.scheme != '') { | 84 if (scriptUri.scheme != '') { |
| 93 // Script has a scheme, assume that it is fully formed. | 85 // Script has a scheme, assume that it is fully formed. |
| 94 _entryPointScript = scriptUri; | 86 _entryPointScript = scriptUri; |
| 95 } else { | 87 } else { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 111 } | 103 } |
| 112 var baseUri = Uri.parse(base); | 104 var baseUri = Uri.parse(base); |
| 113 if (userString.startsWith(_DART_EXT)) { | 105 if (userString.startsWith(_DART_EXT)) { |
| 114 var uri = userString.substring(_DART_EXT.length); | 106 var uri = userString.substring(_DART_EXT.length); |
| 115 return '$_DART_EXT${baseUri.resolve(uri)}'; | 107 return '$_DART_EXT${baseUri.resolve(uri)}'; |
| 116 } else { | 108 } else { |
| 117 return baseUri.resolve(userString).toString(); | 109 return baseUri.resolve(userString).toString(); |
| 118 } | 110 } |
| 119 } | 111 } |
| 120 | 112 |
| 121 | |
| 122 Uri _resolvePackageUri(Uri uri) { | 113 Uri _resolvePackageUri(Uri uri) { |
| 123 if (!uri.host.isEmpty) { | 114 if (!uri.host.isEmpty) { |
| 124 var path = '${uri.host}${uri.path}'; | 115 var path = '${uri.host}${uri.path}'; |
| 125 var right = 'package:$path'; | 116 var right = 'package:$path'; |
| 126 var wrong = 'package://$path'; | 117 var wrong = 'package://$path'; |
| 127 | 118 |
| 128 throw "URIs using the 'package:' scheme should look like " | 119 throw "URIs using the 'package:' scheme should look like " |
| 129 "'$right', not '$wrong'."; | 120 "'$right', not '$wrong'."; |
| 130 } | 121 } |
| 131 | 122 |
| 132 var packageRoot = _packageRoot == null ? | 123 var packageRoot = _packageRoot == null |
| 133 _entryPointScript.resolve('packages/') : | 124 ? _entryPointScript.resolve('packages/') |
| 134 _packageRoot; | 125 : _packageRoot; |
| 135 return packageRoot.resolve(uri.path); | 126 return packageRoot.resolve(uri.path); |
| 136 } | 127 } |
| 137 | 128 |
| 138 | |
| 139 int _numOutstandingLoadRequests = 0; | 129 int _numOutstandingLoadRequests = 0; |
| 140 | 130 |
| 141 // TODO(zra): Enable loading libraries over http. | 131 // TODO(zra): Enable loading libraries over http. |
| 142 // void _httpGet(Uri uri, String libraryUri, loadCallback(List<int> data)) { | 132 // void _httpGet(Uri uri, String libraryUri, loadCallback(List<int> data)) { |
| 143 // } | 133 // } |
| 144 | 134 |
| 145 | |
| 146 void _signalDoneLoading() native "Builtin_DoneLoading"; | 135 void _signalDoneLoading() native "Builtin_DoneLoading"; |
| 147 | 136 |
| 148 | 137 void _loadScriptCallback(int tag, String uri, String libraryUri, |
| 149 void _loadScriptCallback(int tag, String uri, String libraryUri, List<int> data) | 138 List<int> data) native "Builtin_LoadScript"; |
| 150 native "Builtin_LoadScript"; | |
| 151 | |
| 152 | 139 |
| 153 void _loadScript(int tag, String uri, String libraryUri, List<int> data) { | 140 void _loadScript(int tag, String uri, String libraryUri, List<int> data) { |
| 154 _loadScriptCallback(tag, uri, libraryUri, data); | 141 _loadScriptCallback(tag, uri, libraryUri, data); |
| 155 assert(_numOutstandingLoadRequests > 0); | 142 assert(_numOutstandingLoadRequests > 0); |
| 156 _numOutstandingLoadRequests--; | 143 _numOutstandingLoadRequests--; |
| 157 if (_logBuiltin) { | 144 if (_logBuiltin) { |
| 158 _print("native Builtin_LoadScript($uri) completed, " | 145 _print("native Builtin_LoadScript($uri) completed, " |
| 159 "${_numOutstandingLoadRequests} requests remaining"); | 146 "${_numOutstandingLoadRequests} requests remaining"); |
| 160 } | 147 } |
| 161 if (_numOutstandingLoadRequests == 0) { | 148 if (_numOutstandingLoadRequests == 0) { |
| 162 _signalDoneLoading(); | 149 _signalDoneLoading(); |
| 163 } | 150 } |
| 164 } | 151 } |
| 165 | 152 |
| 166 | 153 void _asyncLoadErrorCallback( |
| 167 void _asyncLoadErrorCallback(uri, libraryUri, error) | 154 uri, libraryUri, error) native "Builtin_AsyncLoadError"; |
| 168 native "Builtin_AsyncLoadError"; | |
| 169 | 155 |
| 170 void _asyncLoadError(uri, libraryUri, error) { | 156 void _asyncLoadError(uri, libraryUri, error) { |
| 171 assert(_numOutstandingLoadRequests > 0); | 157 assert(_numOutstandingLoadRequests > 0); |
| 172 if (_logBuiltin) { | 158 if (_logBuiltin) { |
| 173 _print("_asyncLoadError($uri), error: $error"); | 159 _print("_asyncLoadError($uri), error: $error"); |
| 174 } | 160 } |
| 175 _numOutstandingLoadRequests--; | 161 _numOutstandingLoadRequests--; |
| 176 _asyncLoadErrorCallback(uri, libraryUri, error); | 162 _asyncLoadErrorCallback(uri, libraryUri, error); |
| 177 if (_numOutstandingLoadRequests == 0) { | 163 if (_numOutstandingLoadRequests == 0) { |
| 178 _signalDoneLoading(); | 164 _signalDoneLoading(); |
| 179 } | 165 } |
| 180 } | 166 } |
| 181 | 167 |
| 182 | |
| 183 // Create a Uri of 'userUri'. If the input uri is a package uri, then the | 168 // Create a Uri of 'userUri'. If the input uri is a package uri, then the |
| 184 // package uri is resolved. | 169 // package uri is resolved. |
| 185 Uri _createUri(String userUri) { | 170 Uri _createUri(String userUri) { |
| 186 var uri = Uri.parse(userUri); | 171 var uri = Uri.parse(userUri); |
| 187 if (_logBuiltin) { | 172 if (_logBuiltin) { |
| 188 _print('# Creating uri for: $uri'); | 173 _print('# Creating uri for: $uri'); |
| 189 } | 174 } |
| 190 | 175 |
| 191 // TODO(zra): Except for the special handling for package:, URI's should just | 176 // TODO(zra): Except for the special handling for package:, URI's should just |
| 192 // be sent to the network stack to resolve. | 177 // be sent to the network stack to resolve. |
| 193 switch (uri.scheme) { | 178 switch (uri.scheme) { |
| 194 case '': | 179 case '': |
| 195 case 'file': | 180 case 'file': |
| 196 case 'http': | 181 case 'http': |
| 197 case 'https': | 182 case 'https': |
| 198 return uri; | 183 return uri; |
| 199 case 'package': | 184 case 'package': |
| 200 return _resolvePackageUri(uri); | 185 return _resolvePackageUri(uri); |
| 201 default: | 186 default: |
| 202 // Only handling file, http[s], and package URIs | 187 // Only handling file, http[s], and package URIs |
| 203 // in standalone binary. | 188 // in standalone binary. |
| 204 if (_logBuiltin) { | 189 if (_logBuiltin) { |
| 205 _print('# Unknown scheme (${uri.scheme}) in $uri.'); | 190 _print('# Unknown scheme (${uri.scheme}) in $uri.'); |
| 206 } | 191 } |
| 207 throw 'Not a known scheme: $uri'; | 192 throw 'Not a known scheme: $uri'; |
| 208 } | 193 } |
| 209 } | 194 } |
| 210 | 195 |
| 211 | |
| 212 // TODO(zra): readSync and enumerateFiles are exposed for testing purposes only. | 196 // TODO(zra): readSync and enumerateFiles are exposed for testing purposes only. |
| 213 // Eventually, there will be different builtin libraries for testing and | 197 // Eventually, there will be different builtin libraries for testing and |
| 214 // production(i.e. the content handler). In the content handler's builtin | 198 // production(i.e. the content handler). In the content handler's builtin |
| 215 // library, File IO capabilities will be removed. | 199 // library, File IO capabilities will be removed. |
| 216 // This uses the synchronous base::ReadFileToString exposed by Mojo. | 200 // This uses the synchronous base::ReadFileToString exposed by Mojo. |
| 217 List<int> readSync(String uri) native "Builtin_ReadSync"; | 201 List<int> readSync(String uri) native "Builtin_ReadSync"; |
| 218 | 202 |
| 219 // This uses base::FileEnumerator. | 203 // This uses base::FileEnumerator. |
| 220 List<String> enumerateFiles(String path) native "Builtin_EnumerateFiles"; | 204 List<String> enumerateFiles(String path) native "Builtin_EnumerateFiles"; |
| 221 | 205 |
| 222 // Asynchronously loads script data through a http[s] or file uri. | 206 // Asynchronously loads script data through a http[s] or file uri. |
| 223 _loadDataAsync(int tag, String uri, String libraryUri, List<int> source) { | 207 _loadDataAsync(int tag, String uri, String libraryUri, List<int> source) { |
| 224 if (tag == null) { | 208 if (tag == null) { |
| 225 uri = _resolveScriptUri(uri); | 209 uri = _resolveScriptUri(uri); |
| 226 } | 210 } |
| 227 Uri resourceUri = _createUri(uri); | 211 Uri resourceUri = _createUri(uri); |
| 228 _numOutstandingLoadRequests++; | 212 _numOutstandingLoadRequests++; |
| 229 if (_logBuiltin) { | 213 if (_logBuiltin) { |
| 230 _print("_loadDataAsync($uri), " | 214 _print("_loadDataAsync($uri), " |
| 231 "${_numOutstandingLoadRequests} requests outstanding"); | 215 "${_numOutstandingLoadRequests} requests outstanding"); |
| 232 } | 216 } |
| 233 if (source != null) { | 217 if (source != null) { |
| 234 _loadScript(tag, uri, libraryUri, source); | 218 _loadScript(tag, uri, libraryUri, source); |
| 235 return; | 219 return; |
| 236 } | 220 } |
| 237 if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) { | 221 if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) { |
| 238 // TODO(zra): Enable library loading over http. | 222 // TODO(zra): Enable library loading over http. |
| 239 // _httpGet(resourceUri, libraryUri, (data) { | 223 // _httpGet(resourceUri, libraryUri, (data) { |
| 240 // _loadScript(tag, uri, libraryUri, data); | 224 // _loadScript(tag, uri, libraryUri, data); |
| 241 // }); | 225 // }); |
| 242 throw 'Cannot load http, yet.'; | 226 throw 'Cannot load http, yet.'; |
| 243 } else { | 227 } else { |
| 244 // Mojo does not expose any asynchronous file IO calls, but we'll maintain | 228 // Mojo does not expose any asynchronous file IO calls, but we'll maintain |
| 245 // the same structure as the standalone embedder here in case it ever does. | 229 // the same structure as the standalone embedder here in case it ever does. |
| 246 var data = readSync(resourceUri.toFilePath()); | 230 var data = readSync(resourceUri.toFilePath()); |
| 247 _loadScript(tag, uri, libraryUri, data); | 231 _loadScript(tag, uri, libraryUri, data); |
| 248 } | 232 } |
| 249 } | 233 } |
| OLD | NEW |