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

Side by Side Diff: frog/leg/native_emitter.dart

Issue 9583006: Support the literal kind for native classes (ie Console). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 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 | « frog/leg/emitter.dart ('k') | frog/leg/native_handler.dart » ('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 class NativeEmitter { 5 class NativeEmitter {
6 6
7 Compiler compiler; 7 Compiler compiler;
8 bool addedDynamicFunction = false; 8 bool addedDynamicFunction = false;
9 bool addedTypeNameOfFunction = false; 9 bool addedTypeNameOfFunction = false;
10 bool addedDefPropFunction = false; 10 bool addedDefPropFunction = false;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 buffer.add('\n'); 200 buffer.add('\n');
201 } 201 }
202 202
203 void addNativePropertyIfNecessary(StringBuffer buffer) { 203 void addNativePropertyIfNecessary(StringBuffer buffer) {
204 if (addedNativeProperty) return; 204 if (addedNativeProperty) return;
205 addedNativeProperty = true; 205 addedNativeProperty = true;
206 buffer.add(buildNativePropertyCode()); 206 buffer.add(buildNativePropertyCode());
207 buffer.add('\n'); 207 buffer.add('\n');
208 } 208 }
209 209
210 void generateNativeLiteral(ClassElement classElement, StringBuffer buffer) {
211 String quotedNative = classElement.nativeName.slowToString();
212 String nativeCode = quotedNative.substring(2, quotedNative.length - 1);
213 String className = compiler.namer.getName(classElement);
214 buffer.add(className);
215 buffer.add(' = ');
216 buffer.add(nativeCode);
217 buffer.add(';\n');
218
219 String attachTo(name) => "$className.$name";
220
221 for (Element member in classElement.members) {
222 if (member.isInstanceMember()) {
223 compiler.emitter.addInstanceMember(
224 member, attachTo, buffer, isNative: true);
225 }
226 }
227 }
228
229 bool isNativeLiteral(String nativeName) {
230 return nativeName[1] === '=';
231 }
232
233 bool isNativeGlobal(String nativeName) {
234 return nativeName[1] === '@';
235 }
210 236
211 void generateNativeClass(ClassElement classElement, StringBuffer buffer) { 237 void generateNativeClass(ClassElement classElement, StringBuffer buffer) {
212 nativeClasses.add(classElement); 238 nativeClasses.add(classElement);
213 239
214 assert(classElement.backendMembers.isEmpty()); 240 assert(classElement.backendMembers.isEmpty());
215 String nativeName = classElement.nativeName.slowToString(); 241 String nativeName = classElement.nativeName.slowToString();
216 if (nativeName[1] === '@') { 242 if (isNativeLiteral(nativeName)) {
243 generateNativeLiteral(classElement, buffer);
244 // The native literal kind needs to be dealt with specially when
245 // generating code for it.
246 return;
247 }
248
249 if (isNativeGlobal(nativeName)) {
217 // Global object, just be like the other types for now. 250 // Global object, just be like the other types for now.
218 nativeName = nativeName.substring(3, nativeName.length - 1); 251 nativeName = nativeName.substring(3, nativeName.length - 1);
219 } else { 252 } else {
220 nativeName = nativeName.substring(2, nativeName.length - 1); 253 nativeName = nativeName.substring(2, nativeName.length - 1);
221 } 254 }
222 bool hasUsedSelectors = false; 255 bool hasUsedSelectors = false;
223 256
224 String attachTo(name) => "$dynamicName('$name').$nativeName"; 257 String attachTo(String name) {
258 hasUsedSelectors = true;
259 addDynamicFunctionIfNecessary(buffer);
260 return "$dynamicName('$name').$nativeName";
261 }
225 262
226 for (Element member in classElement.members) { 263 for (Element member in classElement.members) {
227 if (member.isInstanceMember()) { 264 if (member.isInstanceMember()) {
228 String memberName = compiler.namer.getName(member); 265 compiler.emitter.addInstanceMember(
229 if (member.kind === ElementKind.FUNCTION 266 member, attachTo, buffer, isNative: true);
230 || member.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY
231 || member.kind === ElementKind.GETTER
232 || member.kind === ElementKind.SETTER) {
233 String codeBlock = compiler.universe.generatedCode[member];
234 if (codeBlock == null) continue;
235 addDynamicFunctionIfNecessary(buffer);
236 hasUsedSelectors = true;
237 buffer.add(
238 "$dynamicName('$memberName').$nativeName = $codeBlock;\n");
239 codeBlock = compiler.universe.generatedBailoutCode[member];
240 if (codeBlock !== null) {
241 String name = compiler.namer.getBailoutName(member);
242 buffer.add("$dynamicName('$name').$nativeName = $codeBlock;\n");
243 }
244 FunctionElement function = member;
245 FunctionParameters parameters = function.computeParameters(compiler);
246 if (!parameters.optionalParameters.isEmpty()) {
247 compiler.emitter.addParameterStubs(
248 member, attachTo, buffer, isNative: true);
249 }
250 } else if (member.kind === ElementKind.FIELD) {
251 if (compiler.universe.invokedSetters.contains(member.name)) {
252 addDynamicFunctionIfNecessary(buffer);
253 hasUsedSelectors = true;
254 String setterName = compiler.namer.setterName(member.name);
255 buffer.add(
256 "$dynamicName('$setterName').$nativeName = function(v){\n" +
257 ' this.${member.name.slowToString()} = v;\n};\n');
258 }
259 if (compiler.universe.invokedGetters.contains(member.name)) {
260 addDynamicFunctionIfNecessary(buffer);
261 hasUsedSelectors = true;
262 String getterName = compiler.namer.getterName(member.name);
263 buffer.add(
264 "$dynamicName('$getterName').$nativeName = function(){\n" +
265 ' return this.${member.name.slowToString()};\n};\n');
266 }
267 } else {
268 compiler.internalError('unexpected kind: "${member.kind}"',
269 element: member);
270 }
271 if (member.kind == ElementKind.GETTER
272 || member.kind == ElementKind.FIELD) {
273 Set<Selector> selectors = compiler.universe.invokedNames[member.name];
274 if (selectors !== null && !selectors.isEmpty()) {
275 emitCallStubForGetter(buffer, attachTo, member, selectors);
276 }
277 } else if (member.kind == ElementKind.FUNCTION) {
278 if (compiler.universe.invokedGetters.contains(member.name)) {
279 emitDynamicFunctionGetter(buffer, attachTo, member);
280 }
281 }
282 } 267 }
283 } 268 }
284 269
285 addNativePropertyIfNecessary(buffer); 270 addNativePropertyIfNecessary(buffer);
286 // Create an object that contains the is checks properties. The 271 // Create an object that contains the is checks properties. The
287 // object will be used when entering [buildDynamicIsCheckCode]. 272 // object will be used when entering [buildDynamicIsCheckCode].
288 buffer.add('${compiler.namer.ISOLATE}.prototype.native.$nativeName = { '); 273 buffer.add('${compiler.namer.ISOLATE}.prototype.native.$nativeName = { ');
289 List<String> tests = <String>[]; 274 List<String> tests = <String>[];
290 275
291 ClassElement objectClass = 276 ClassElement objectClass =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 // For example, for the following Dart method: 312 // For example, for the following Dart method:
328 // foo([x, y, z]); 313 // foo([x, y, z]);
329 // The call: 314 // The call:
330 // foo(y: 1) 315 // foo(y: 1)
331 // must be turned into a JS call to: 316 // must be turned into a JS call to:
332 // foo(null, y). 317 // foo(null, y).
333 318
334 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange( 319 List<String> nativeArgumentsBuffer = argumentsBuffer.getRange(
335 0, indexOfLastOptionalArgumentInParameters + 1); 320 0, indexOfLastOptionalArgumentInParameters + 1);
336 321
322 ClassElement classElement = member.enclosingElement;
323 String nativeName = classElement.nativeName.slowToString();
337 String nativeArguments = Strings.join(nativeArgumentsBuffer, ","); 324 String nativeArguments = Strings.join(nativeArgumentsBuffer, ",");
338 325
326 if (isNativeLiteral(nativeName)) {
327 // If it's the native literal, we know there is no subclass, so
328 // we can call the method directly.
329 buffer.add(' return this.${member.name.slowToString()}');
330 buffer.add('($nativeArguments)');
331 return;
332 }
333
339 buffer.add(' if (Object.getPrototypeOf(this).hasOwnProperty('); 334 buffer.add(' if (Object.getPrototypeOf(this).hasOwnProperty(');
340 buffer.add("'$invocationName')) {\n"); 335 buffer.add("'$invocationName')) {\n");
341 buffer.add(' return this.${member.name.slowToString()}'); 336 buffer.add(' return this.${member.name.slowToString()}');
342 buffer.add('($nativeArguments)'); 337 buffer.add('($nativeArguments)');
343 buffer.add('\n }\n'); 338 buffer.add('\n }\n');
344 buffer.add(' return Object.prototype.$invocationName.call(this'); 339 buffer.add(' return Object.prototype.$invocationName.call(this');
345 buffer.add(stubParameters == '' ? '' : ', $stubParameters'); 340 buffer.add(stubParameters == '' ? '' : ', $stubParameters');
346 buffer.add(');'); 341 buffer.add(');');
347 } 342 }
348 343
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 entries.add("\n ['$clsName', ${tagDefns[clsName]}]"); 473 entries.add("\n ['$clsName', ${tagDefns[clsName]}]");
479 } 474 }
480 buffer.add(Strings.join(entries, ',')); 475 buffer.add(Strings.join(entries, ','));
481 buffer.add('];\n'); 476 buffer.add('];\n');
482 buffer.add('$dynamicSetMetadataName(table);\n'); 477 buffer.add('$dynamicSetMetadataName(table);\n');
483 478
484 buffer.add('})();\n'); 479 buffer.add('})();\n');
485 } 480 }
486 } 481 }
487 } 482 }
OLDNEW
« no previous file with comments | « frog/leg/emitter.dart ('k') | frog/leg/native_handler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698