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

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 23045004: Throw when reflecting on elements not covered by a `MirrorsUsed` annotation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address Nicolas' comments. Created 7 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index e7eb3ce1eb92696f13a5652c252591e0ddb73983..4e45ae9ecd9d50ab67c635d3bda650cee081d06c 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -287,6 +287,7 @@ class CodeEmitterTask extends CompilerTask {
static const RANGE2_LAST = 0x7e;
static const RANGE3_FIRST = 0x25; // %&'()*+ encodes 10..16
static const RANGE3_LAST = 0x2b;
+ static const REFLECTION_MARKER = 0x2d;
jsAst.FunctionDeclaration get generateAccessorFunction {
const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
@@ -298,11 +299,19 @@ class CodeEmitterTask extends CompilerTask {
String receiverParamName = compiler.enableMinification ? "r" : "receiver";
String valueParamName = compiler.enableMinification ? "v" : "value";
+ String reflectableField = namer.reflectableField;
// function generateAccessor(field, prototype) {
jsAst.Fun fun = js.fun(['field', 'prototype'], [
js('var len = field.length'),
js('var code = field.charCodeAt(len - 1)'),
+ js('var reflectable = false'),
+ js.if_('code == $REFLECTION_MARKER', [
+ js('len--'),
+ js('code = field.charCodeAt(len - 1)'),
+ js('field = field.substring(0, len)'),
+ js('reflectable = true')
+ ]),
js('code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))'
' ? code - $RANGE1_ADJUST'
' : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))'
@@ -329,7 +338,10 @@ class CodeEmitterTask extends CompilerTask {
js('var receiver = (getterCode & 1) ? "this" : "$receiverParamName"'),
js('var body = "return " + receiver + "." + field'),
js('prototype["${namer.getterPrefix}" + accessorName] = '
- 'new Function(args, body)')
+ 'new Function(args, body)'),
+ js.if_('!reflectable', [
+ js('prototype["${namer.getterPrefix}" + accessorName].'
+ '$reflectableField = false')])
]),
// if (needsSetter) {
@@ -340,7 +352,10 @@ class CodeEmitterTask extends CompilerTask {
js('var receiver = (setterCode & 1) ? "this" : "$receiverParamName"'),
js('var body = receiver + "." + field + "$_=$_$valueParamName"'),
js('prototype["${namer.setterPrefix}" + accessorName] = '
- 'new Function(args, body)')
+ 'new Function(args, body)'),
+ js.if_('!reflectable', [
+ js('prototype["${namer.setterPrefix}" + accessorName].'
+ '$reflectableField = false')])
]),
]),
@@ -1099,7 +1114,9 @@ class CodeEmitterTask extends CompilerTask {
String reflectionName = getReflectionName(selector, invocationName);
if (reflectionName != null) {
- defineStub('+$reflectionName', js('0'));
+ var reflectable =
+ js(backend.isAccessibleByReflection(member) ? '1' : '0');
+ defineStub('+$reflectionName', reflectable);
}
}
@@ -1270,7 +1287,9 @@ class CodeEmitterTask extends CompilerTask {
builder.addProperty(name, code);
String reflectionName = getReflectionName(member, name);
if (reflectionName != null) {
- builder.addProperty('+$reflectionName', js('0'));
+ var reflectable =
+ js(backend.isAccessibleByReflection(member) ? '1' : '0');
+ builder.addProperty('+$reflectionName', reflectable);
}
code = backend.generatedBailoutCode[member];
if (code != null) {
@@ -1325,7 +1344,10 @@ class CodeEmitterTask extends CompilerTask {
String getter = '${namer.getterPrefix}$base';
mangledFieldNames[getter] = name;
recordedMangledNames.add(getter);
- return null;
+ // TODO(karlklose,ahe): we do not actually need to store information
+ // about the name of this setter in the output, but it is needed for
+ // marking the function as invokable by reflection.
+ return '$name=';
}
if (elementOrSelector is Selector
|| elementOrSelector.isFunction()
@@ -1861,6 +1883,9 @@ class CodeEmitterTask extends CompilerTask {
buffer.write(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]);
}
}
+ if (backend.isAccessibleByReflection(field)) {
+ buffer.write(new String.fromCharCode(REFLECTION_MARKER));
+ }
}
});
}
@@ -2300,7 +2325,8 @@ class CodeEmitterTask extends CompilerTask {
emitStaticFunction(buffer, name, code);
String reflectionName = getReflectionName(element, name);
if (reflectionName != null) {
- buffer.write(',$n$n"+$reflectionName":${_}0');
+ var reflectable = backend.isAccessibleByReflection(element) ? 1 : 0;
+ buffer.write(',$n$n"+$reflectionName":${_}$reflectable');
}
jsAst.Expression bailoutCode = backend.generatedBailoutCode[element];
if (bailoutCode != null) {
@@ -4030,6 +4056,7 @@ class CodeEmitterTask extends CompilerTask {
// TODO(ahe): This code should be integrated in finishClasses.
String getReflectionDataParser() {
String metadataField = '"${namer.metadataField}"';
+ String reflectableField = namer.reflectableField;
return '''
(function (reflectionData) {
'''
@@ -4078,7 +4105,9 @@ class CodeEmitterTask extends CompilerTask {
var previousProperty;
if (firstChar === "+") {
mangledGlobalNames[previousProperty] = property.substring(1);
- if (element && element.length) ''' // Breaking long line.
+ descriptor[previousProperty].''' // Break long line.
+'''$reflectableField = (descriptor[property] == 1);
+ if (element && element.length) ''' // Break long line.
'''init.interfaces[previousProperty] = element;
} else if (firstChar === "@") {
property = property.substring(1);
@@ -4097,6 +4126,8 @@ class CodeEmitterTask extends CompilerTask {
processStatics(init.statics[property] = element[prop]);
} else if (firstChar === "+") {
mangledNames[previousProp] = prop.substring(1);
+ element[previousProp].''' // Break long line.
+'''$reflectableField = (element[prop] == 1);
} else if (firstChar === "@" && prop !== "@") {
newDesc[prop.substring(1)][$metadataField] = element[prop];
} else {

Powered by Google App Engine
This is Rietveld 408576698