Merge branch 'master' into harmony-v3.0.5

This commit is contained in:
alexlamsl
2017-05-15 18:58:54 +08:00
15 changed files with 479 additions and 265 deletions

View File

@@ -932,7 +932,7 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
$documentation: "Base class for literal object properties",
$propdoc: {
key: "[string|AST_Node] the property name converted to a string for ObjectKeyVal. For setters, getters and computed property this is an arbitrary AST_Node",
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
},
_walk: function(visitor) {
return visitor._visit(this, function(){
@@ -1018,10 +1018,6 @@ var AST_NewTarget = DEFNODE("NewTarget", null, {
$documentation: "A reference to new.target"
});
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
$documentation: "The name of a property accessor (setter/getter function)"
}, AST_Symbol);
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
}, AST_Symbol);

View File

@@ -361,16 +361,27 @@ merge(Compressor.prototype, {
// So existing transformation rules can work on them.
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
d.fixed = function() {
return iife.args[i] || make_node(AST_Undefined, iife);
};
mark(d, true);
if (!node.uses_arguments && d.fixed === undefined) {
d.fixed = function() {
return iife.args[i] || make_node(AST_Undefined, iife);
};
mark(d, true);
} else {
d.fixed = false;
}
});
}
descend();
pop();
return true;
}
if (node instanceof AST_Accessor) {
var save_ids = safe_ids;
safe_ids = Object.create(null);
descend();
safe_ids = save_ids;
return true;
}
if (node instanceof AST_Binary
&& (node.operator == "&&" || node.operator == "||")) {
node.left.walk(tw);
@@ -498,7 +509,9 @@ merge(Compressor.prototype, {
function reset_def(def) {
def.escaped = false;
if (!def.global || def.orig[0] instanceof AST_SymbolConst || compressor.toplevel(def)) {
if (def.scope.uses_eval) {
def.fixed = false;
} else if (!def.global || def.orig[0] instanceof AST_SymbolConst || compressor.toplevel(def)) {
def.fixed = undefined;
} else {
def.fixed = false;
@@ -1240,12 +1253,12 @@ merge(Compressor.prototype, {
&& !node.expression.has_side_effects(compressor);
}
// may_eq_null()
// returns true if this node may evaluate to null or undefined
// may_throw_on_access()
// returns true if this node may be null, undefined or contain `AST_Accessor`
(function(def) {
AST_Node.DEFMETHOD("may_eq_null", function(compressor) {
AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
var pure_getters = compressor.option("pure_getters");
return !pure_getters || this._eq_null(pure_getters);
return !pure_getters || this._throw_on_access(pure_getters);
});
function is_strict(pure_getters) {
@@ -1257,7 +1270,12 @@ merge(Compressor.prototype, {
def(AST_Undefined, return_true);
def(AST_Constant, return_false);
def(AST_Array, return_false);
def(AST_Object, return_false);
def(AST_Object, function(pure_getters) {
if (!is_strict(pure_getters)) return false;
for (var i = this.properties.length; --i >=0;)
if (this.properties[i].value instanceof AST_Accessor) return true;
return false;
});
def(AST_Function, return_false);
def(AST_UnaryPostfix, return_false);
def(AST_UnaryPrefix, function() {
@@ -1266,33 +1284,33 @@ merge(Compressor.prototype, {
def(AST_Binary, function(pure_getters) {
switch (this.operator) {
case "&&":
return this.left._eq_null(pure_getters);
return this.left._throw_on_access(pure_getters);
case "||":
return this.left._eq_null(pure_getters)
&& this.right._eq_null(pure_getters);
return this.left._throw_on_access(pure_getters)
&& this.right._throw_on_access(pure_getters);
default:
return false;
}
})
def(AST_Assign, function(pure_getters) {
return this.operator == "="
&& this.right._eq_null(pure_getters);
&& this.right._throw_on_access(pure_getters);
})
def(AST_Conditional, function(pure_getters) {
return this.consequent._eq_null(pure_getters)
|| this.alternative._eq_null(pure_getters);
return this.consequent._throw_on_access(pure_getters)
|| this.alternative._throw_on_access(pure_getters);
})
def(AST_Sequence, function(pure_getters) {
return this.expressions[this.expressions.length - 1]._eq_null(pure_getters);
return this.expressions[this.expressions.length - 1]._throw_on_access(pure_getters);
});
def(AST_SymbolRef, function(pure_getters) {
if (this.is_undefined) return true;
if (!is_strict(pure_getters)) return false;
var fixed = this.fixed_value();
return !fixed || fixed._eq_null(pure_getters);
return !fixed || fixed._throw_on_access(pure_getters);
});
})(function(node, func) {
node.DEFMETHOD("_eq_null", func);
node.DEFMETHOD("_throw_on_access", func);
});
/* -----[ boolean/negation helpers ]----- */
@@ -1853,11 +1871,11 @@ merge(Compressor.prototype, {
return any(this.elements, compressor);
});
def(AST_Dot, function(compressor){
return this.expression.may_eq_null(compressor)
return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor);
});
def(AST_Sub, function(compressor){
return this.expression.may_eq_null(compressor)
return this.expression.may_throw_on_access(compressor)
|| this.expression.has_side_effects(compressor)
|| this.property.has_side_effects(compressor);
});
@@ -2492,6 +2510,7 @@ merge(Compressor.prototype, {
var args = trim(this.args, compressor, first_in_statement);
return args && make_sequence(this, args);
});
def(AST_Accessor, return_null);
def(AST_Function, return_null);
def(AST_Binary, function(compressor, first_in_statement){
var right = this.right.drop_side_effect_free(compressor);
@@ -2559,11 +2578,11 @@ merge(Compressor.prototype, {
return values && make_sequence(this, values);
});
def(AST_Dot, function(compressor, first_in_statement){
if (this.expression.may_eq_null(compressor)) return this;
if (this.expression.may_throw_on_access(compressor)) return this;
return this.expression.drop_side_effect_free(compressor, first_in_statement);
});
def(AST_Sub, function(compressor, first_in_statement){
if (this.expression.may_eq_null(compressor)) return this;
if (this.expression.may_throw_on_access(compressor)) return this;
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
var property = this.property.drop_side_effect_free(compressor);

View File

@@ -111,23 +111,19 @@
},
Property: function(M) {
var key = M.key;
var name = key.type == "Identifier" ? key.name : key.value;
var args = {
start : my_start_token(key),
end : my_end_token(M.value),
key : name,
key : key.type == "Identifier" ? key.name : key.value,
value : from_moz(M.value)
};
switch (M.kind) {
case "init":
return new AST_ObjectKeyVal(args);
case "set":
args.value.name = from_moz(key);
return new AST_ObjectSetter(args);
case "get":
args.value.name = from_moz(key);
return new AST_ObjectGetter(args);
}
if (M.kind == "init") return new AST_ObjectKeyVal(args);
args.key = new AST_SymbolMethod({
name: args.key
});
args.value = new AST_Accessor(args.value);
if (M.kind == "get") return new AST_ObjectGetter(args);
if (M.kind == "set") return new AST_ObjectSetter(args);
},
ArrayExpression: function(M) {
return new AST_Array({
@@ -260,10 +256,7 @@
map("CallExpression", AST_Call, "callee>expression, arguments@args");
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
return {
type: "Program",
body: M.body.map(to_moz)
};
return to_moz_scope("Program", M);
});
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
@@ -271,7 +264,7 @@
type: "FunctionDeclaration",
id: to_moz(M.name),
params: M.argnames.map(to_moz),
body: to_moz_block(M)
body: to_moz_scope("BlockStatement", M)
}
});
@@ -280,7 +273,7 @@
type: "FunctionExpression",
id: to_moz(M.name),
params: M.argnames.map(to_moz),
body: to_moz_block(M)
body: to_moz_scope("BlockStatement", M)
}
});
@@ -386,11 +379,10 @@
});
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
var key = (
is_identifier(M.key)
? {type: "Identifier", name: M.key}
: {type: "Literal", value: M.key}
);
var key = {
type: "Literal",
value: M.key instanceof AST_SymbolMethod ? M.key.name : M.key
};
var kind;
if (M instanceof AST_ObjectKeyVal) {
kind = "init";
@@ -551,8 +543,8 @@
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
exports, my_start_token, my_end_token, from_moz
);
me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
to_moz, to_moz_block
me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
to_moz, to_moz_block, to_moz_scope
);
MOZ_TO_ME[moztype] = moz_to_me;
def_to_moz(mytype, me_to_moz);
@@ -610,4 +602,14 @@
};
};
function to_moz_scope(type, node) {
var body = node.body.map(to_moz);
if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
}
return {
type: type,
body: body
};
};
})();

View File

@@ -976,24 +976,20 @@ function parse($TEXT, options) {
handle_regexp();
switch (S.token.type) {
case "string":
var dir = false;
if (S.in_directives === true) {
if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) {
if (S.in_directives) {
tmp = peek();
if (S.token.raw.indexOf("\\") == -1
&& (tmp.nlb
|| is_token(tmp, "eof")
|| is_token(tmp, "punc", ";")
|| is_token(tmp, "punc", "}"))) {
S.input.add_directive(S.token.value);
} else {
S.in_directives = false;
}
}
var dir = S.in_directives, stat = simple_statement();
if (dir) {
return new AST_Directive({
start : stat.body.start,
end : stat.body.end,
quote : stat.body.quote,
value : stat.body.value,
});
}
return stat;
return dir ? new AST_Directive(stat.body) : stat;
case "template_head":
case "num":
case "regexp":

View File

@@ -473,11 +473,6 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
return def && def.unmangleable(options);
});
// property accessors are not mangleable
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
return true;
});
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", function(){
return false;