<commit_before>/*******************************************************************************
 * Copyright (c) 2013 <NAME>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     <NAME> - initial API and implementation
 *******************************************************************************/
 
 /*global require exports */
 
 var asg = require('./asg'),
     ast = require('./ast'),
     escodegen = require('escodegen'),
     util = require('./util'),
     add = util.add,
     isObject = util.isObject,
     setHiddenProp = util.setHiddenProp,
     mkAssignStmt = ast.mkAssignStmt,
     mkIdentifier = ast.mkIdentifier,
     mkMemberExpression = ast.mkMemberExpression,
     mkCallStmt = ast.mkCallStmt,
     Union = require('./Union').Union,
     ObjModel = require('./ObjModel').ObjModel,
     ArrayModel = require('./ArrayModel').ArrayModel,
     GlobalModel = require('./GlobalModel').GlobalModel,
     InstanceModel = require('./InstanceModel').InstanceModel,
     FunctionModel = require('./FunctionModel').FunctionModel,
     PrimitiveModel = require('./PrimitiveModel'),
     ClientObjModel = require('./ClientObjModel').ClientObjModel,
     builtins = require('./builtins');
     
require('./circularity');
require('./hashconsing');
require('./find_used_client_objects');

/** The observer is notified by the dynamic instrumentation framework of events happening in the instrumented program. */
function Observer() {
	this.current_fn = [];
}

Observer.prototype.tagGlobal = function(global) {
	var tag = new GlobalModel(global);
	util.setHiddenProp(global, '__tag', tag);
	builtins.tagBuiltins(global);
	return tag;
};

Observer.prototype.setGlobal = function(global) {
	this.global = global;
};

var tagLiteral = Observer.prototype.tagLiteral = function(pos, lit) {
	var tp = typeof lit, tag;
	switch(tp) {
	case 'undefined':
		return PrimitiveModel.UNDEFINED;
	case 'boolean':
		return PrimitiveModel.BOOLEAN;
	case 'number':
		return PrimitiveModel.NUMBER;
	case 'string':
		return PrimitiveModel.STRING;
	case 'object':
		if(!lit)
			return PrimitiveModel.NULL;
		if(lit instanceof RegExp)
			return PrimitiveModel.REGEXP;
		tag = Array.isArray(lit) ? ArrayModel.make(pos) : ObjModel.make(pos);
		Object.defineProperty(lit, "__tag", { enumerable: false, writable: true, value: tag });
		return tag;
	case 'function':
		tag = FunctionModel.make(pos);
		Object.defineProperty(lit, "__tag", { enumerable: false, writable: true, value: tag });
		return tag;
	}
};

Observer.prototype.tagForInVar = function() {
	return PrimitiveModel.STRING;
};

Observer.prototype.tagNativeException = function() {
	return new ObjModel();
};

Observer.prototype.tagNativeArgument = function(callee, arg, idx) {
	if(arg && arg.hasOwnProperty('__tag'))
		return arg.__tag;
		
	var tag = ClientObjModel.make(callee.__tag, idx);
	if(Object(arg) === arg) {
		Object.defineProperty(arg, "__tag", { enumerable: false, writable: true, value: tag });
	}
	return tag;
};

Observer.prototype.tagNativeResult = Observer.prototype.tagNewNativeInstance = function(res) {
	// check whether it is an object
	if(Object(res) === res) {
		// maybe the object is already tagged?
		if(res.hasOwnProperty('__tag'))
			return res.__tag;
			
		// or maybe it is an instance of a function we know?
		var proto = Object.getPrototypeOf(res);
		if(proto.hasOwnProperty('__tag') && proto.__tag.default_proto_of) {
			return new InstanceModel(proto.__tag.default_proto_of);
		}
		
		// nope, it's just some object
		return new ObjModel();
	} else {
		return this.tagLiteral(null, res);
	}
};

Observer.prototype.tagNativeProperty = function(obj, prop, val) {
	if(Object(val) === val) {
		return val.__tag || new ObjModel();
	} else {
		return this.tagLiteral(null, val);
	}
};

Observer.prototype.tagNewInstance = function(res, callee, args) {
	return callee.getTag().instance_model;
};

Observer.prototype.tagDefaultPrototype = function(fn) {
	return fn.getTag().default_proto_model;
};

Observer.prototype.tagUnOpResult = function(res) {
	return tagLiteral(null, res);<commit_msg>Be a bit more careful about reading property __tag: shouldn't read it from prototype.<commit_after>/*******************************************************************************
 * Copyright (c) 2013 <NAME>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     <NAME> - initial API and implementation
 *******************************************************************************/
 
 /*global require exports */
 
 var asg = require('./asg'),
     ast = require('./ast'),
     escodegen = require('escodegen'),
     util = require('./util'),
     add = util.add,
     isObject = util.isObject,
     setHiddenProp = util.setHiddenProp,
     mkAssignStmt = ast.mkAssignStmt,
     mkIdentifier = ast.mkIdentifier,
     mkMemberExpression = ast.mkMemberExpression,
     mkCallStmt = ast.mkCallStmt,
     Union = require('./Union').Union,
     ObjModel = require('./ObjModel').ObjModel,
     ArrayModel = require('./ArrayModel').ArrayModel,
     GlobalModel = require('./GlobalModel').GlobalModel,
     InstanceModel = require('./InstanceModel').InstanceModel,
     FunctionModel = require('./FunctionModel').FunctionModel,
     PrimitiveModel = require('./PrimitiveModel'),
     ClientObjModel = require('./ClientObjModel').ClientObjModel,
     builtins = require('./builtins');
     
require('./circularity');
require('./hashconsing');
require('./find_used_client_objects');

/** The observer is notified by the dynamic instrumentation framework of events happening in the instrumented program. */
function Observer() {
	this.current_fn = [];
}

Observer.prototype.tagGlobal = function(global) {
	var tag = new GlobalModel(global);
	util.setHiddenProp(global, '__tag', tag);
	builtins.tagBuiltins(global);
	return tag;
};

Observer.prototype.setGlobal = function(global) {
	this.global = global;
};

var tagLiteral = Observer.prototype.tagLiteral = function(pos, lit) {
	var tp = typeof lit, tag;
	switch(tp) {
	case 'undefined':
		return PrimitiveModel.UNDEFINED;
	case 'boolean':
		return PrimitiveModel.BOOLEAN;
	case 'number':
		return PrimitiveModel.NUMBER;
	case 'string':
		return PrimitiveModel.STRING;
	case 'object':
		if(!lit)
			return PrimitiveModel.NULL;
		if(lit instanceof RegExp)
			return PrimitiveModel.REGEXP;
		tag = Array.isArray(lit) ? ArrayModel.make(pos) : ObjModel.make(pos);
		Object.defineProperty(lit, "__tag", { enumerable: false, writable: true, value: tag });
		return tag;
	case 'function':
		tag = FunctionModel.make(pos);
		Object.defineProperty(lit, "__tag", { enumerable: false, writable: true, value: tag });
		return tag;
	}
};

Observer.prototype.tagForInVar = function() {
	return PrimitiveModel.STRING;
};

Observer.prototype.tagNativeException = function() {
	return new ObjModel();
};

Observer.prototype.tagNativeArgument = function(callee, arg, idx) {
	if(arg && arg.hasOwnProperty('__tag'))
		return arg.__tag;
		
	if(callee.hasOwnProperty('__tag')) {
		var tag = ClientObjModel.make(callee.__tag, idx);
		if(Object(arg) === arg) {
			Object.defineProperty(arg, "__tag", { enumerable: false, writable: true, value: tag });
		}
		return tag;
	} else {
		return new ObjModel();
	}
};

var tagNative =
Observer.prototype.tagNativeResult =
Observer.prototype.tagNewNativeInstance =
Observer.prototype.tagCallee = function(res) {
	// check whether it is an object
	if(Object(res) === res) {
		// maybe the object is already tagged?
		if(res.hasOwnProperty('__tag'))
			return res.__tag;
			
		// no; check whether it is a function
		if(typeof res === 'function') {
			return util.setHiddenProp(res, '__tag', new FunctionModel());
		}
			
		// or maybe it is an instance of a function we know?
		var proto = Object.getPrototypeOf(res);
		if(proto.hasOwnProperty('__tag') && proto.__tag.default_proto_of) {
			return util.setHiddenProp(res, '__tag', new InstanceModel(proto.__tag.default_proto_of));
		}
		
		// nope, it's just some object
		return util.setHiddenProp(res, '__tag', new ObjModel());
	} else {
		return this.tagLiteral(null, res);
	}
};

Observer.prototype.tagNativeProperty = function(obj, prop, val) {
	if(Object(val) === val) {
		return val.hasOwnProperty('__tag') && val.__tag || new ObjModel();
	} else {
		return this.tagLiteral(null, val);
	}
};

Observer.prototype.tagNewInstance = function(res, callee, args) {
	return callee.getTag().instance_model;
};

Observer.prototype.tagDefaultPrototype = function(fn) {
	return fn.getTag().default_proto_model;
};

Observer.prototype.tagUnOpResult = function(res) {
	return tagLiteral(null, res);
{'fraction_non_alphanumeric': 0.16670371193598577, 'fraction_numerical': 0.0017781729273171815, 'mean_word_length': 4.480511571254568, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '468152', 'n_tokens_mistral': 2763, 'n_tokens_neox': 2651, 'n_words': 642}