[add] code
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
dist
|
||||||
output.csv
|
output.csv
|
||||||
output/
|
output/
|
||||||
node_modules/
|
node_modules/
|
10
package-lock.json
generated
10
package-lock.json
generated
@@ -23,7 +23,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/eslint-scope": "^8.3.0",
|
"@types/eslint-scope": "^8.3.0",
|
||||||
"@types/estree": "^1.0.8",
|
"@types/estree": "^1.0.8",
|
||||||
"@types/node": "^24.0.0"
|
"@types/node": "^24.0.0",
|
||||||
|
"classnames": "^2.5.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/gen-mapping": {
|
"node_modules/@jridgewell/gen-mapping": {
|
||||||
@@ -424,6 +425,13 @@
|
|||||||
"node": ">=6.0"
|
"node": ">=6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/classnames": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/cli-table": {
|
"node_modules/cli-table": {
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.0.2.tgz",
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/eslint-scope": "^8.3.0",
|
"@types/eslint-scope": "^8.3.0",
|
||||||
"@types/estree": "^1.0.8",
|
"@types/estree": "^1.0.8",
|
||||||
"@types/node": "^24.0.0"
|
"@types/node": "^24.0.0",
|
||||||
|
"classnames": "^2.5.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,10 +4,11 @@ import { getASTAndScope } from './ast/analysis.mjs';
|
|||||||
|
|
||||||
import { getRequireCallsAndConstantArgs } from './calls.mjs';
|
import { getRequireCallsAndConstantArgs } from './calls.mjs';
|
||||||
import { analyze, instrumentString, instrumentDir } from 'jalangi2';
|
import { analyze, instrumentString, instrumentDir } from 'jalangi2';
|
||||||
import { readFileSync ,realpathSync} from 'node:fs';
|
import { readFileSync ,realpathSync ,mkdirSync} from 'node:fs';
|
||||||
|
import { writeFile } from 'node:fs/promises';
|
||||||
|
|
||||||
import {getSliceAndInfoSync} from 'slice-js/dist/slice-code/test/helpers/utils.js';
|
import {getSliceAndInfoSync} from 'slice-js/src/slice-code/test/helpers/utils.js';
|
||||||
import { dirname,join } from 'node:path';
|
import path, { dirname,join } from 'node:path';
|
||||||
/**
|
/**
|
||||||
* Call parameter generation
|
* Call parameter generation
|
||||||
*/
|
*/
|
||||||
@@ -19,18 +20,11 @@ function main() {
|
|||||||
|
|
||||||
const calls = getRequireCallsAndConstantArgs(scopeManager);
|
const calls = getRequireCallsAndConstantArgs(scopeManager);
|
||||||
|
|
||||||
for (const [moduleName, callBoxes] of calls.entries()) {
|
logCallList(calls);
|
||||||
if (moduleName.startsWith('.')) {
|
|
||||||
console.log('Importing', moduleName, callBoxes);
|
|
||||||
} else {
|
|
||||||
console.log(`Module "${moduleName}" - System module. FIXME skipping`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`Call List`, calls);
|
|
||||||
|
|
||||||
|
const writePromises = [];
|
||||||
for (const [moduleName, callBox] of calls) {
|
for (const [moduleName, callBox] of calls) {
|
||||||
// console.log(callBox);
|
if (!isRelativeModule(moduleName)) { // not relative module
|
||||||
if (!moduleName.startsWith('.')) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,36 +34,27 @@ function main() {
|
|||||||
return [...callBox.entries()].flatMap(([methodName, methodArgsList])=>{
|
return [...callBox.entries()].flatMap(([methodName, methodArgsList])=>{
|
||||||
const methodNameNormed = methodName.substring(1);
|
const methodNameNormed = methodName.substring(1);
|
||||||
console.log("Calls for ",methodNameNormed,methodArgsList)
|
console.log("Calls for ",methodNameNormed,methodArgsList)
|
||||||
return methodArgsList.map(methodArgsList=>moduleExports[methodNameNormed].apply(moduleExports[methodNameNormed],methodArgsList));
|
return methodArgsList.map(methodArgsList=>{
|
||||||
|
const methodObj = methodNameNormed===''?moduleExports:moduleExports[methodNameNormed];
|
||||||
|
methodObj.apply(moduleExports[methodNameNormed],methodArgsList)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
},relatedModuleNamePath);
|
},relatedModuleNamePath);
|
||||||
console.log(`Sliced code ${moduleName}\n`,slicedCode);
|
// console.log(`Sliced code ${moduleName}\n`,slicedCode);
|
||||||
|
const writePath = path.resolve('./dist', moduleName);
|
||||||
|
if(writePath===moduleName){
|
||||||
|
throw Error("Will overwrite!!!!");
|
||||||
|
}
|
||||||
|
mkdirSync(path.dirname(writePath),{recursive: true});
|
||||||
|
console.log(`Writing to`,writePath);
|
||||||
|
|
||||||
|
writePromises.push(writeFile(writePath,slicedCode));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function jalangiInstrumentMain() {
|
Promise.all(writePromises).then(p=>{
|
||||||
const FILE_PATH = './test_src/index.cjs';
|
console.log("write finished")
|
||||||
|
}).catch(console.log);
|
||||||
|
|
||||||
const fileString = readFileSync(FILE_PATH).toString();
|
|
||||||
const y = instrumentString(fileString, {});
|
|
||||||
console.log(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Analysis POC
|
|
||||||
*/
|
|
||||||
function jalangiAnalyzeMain() {
|
|
||||||
const FILE_PATH = './test_src/index.cjs';
|
|
||||||
|
|
||||||
const y = analyze(FILE_PATH, ["./node_modules/jalangi2/src/js/sample_analyses/tutorial/LogAll.js", "./src_analysis/analysisCallbackTemplate.cjs"]);
|
|
||||||
// const x = 5;
|
|
||||||
y.then(yp => {
|
|
||||||
console.log("Analysis complete", yp);
|
|
||||||
}).catch(console.error).finally(kek => {
|
|
||||||
console.log("Threw error", kek);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (process.argv[1] === import.meta.filename) {
|
if (process.argv[1] === import.meta.filename) {
|
||||||
@@ -78,3 +63,18 @@ if (process.argv[1] === import.meta.filename) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function logCallList(calls) {
|
||||||
|
for (const [moduleName, callBoxes] of calls.entries()) {
|
||||||
|
if (isRelativeModule(moduleName)) {
|
||||||
|
console.log('Importing', moduleName, callBoxes);
|
||||||
|
} else {
|
||||||
|
console.log(`Module "${moduleName}" - System module. FIXME skipping`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Call List`, calls);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isRelativeModule(moduleName) {
|
||||||
|
return moduleName.startsWith('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1,647 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 Samsung Information Systems America, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Author: Koushik Sen
|
|
||||||
|
|
||||||
// do not remove the following comment
|
|
||||||
// JALANGI DO NOT INSTRUMENT
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file A template for writing a Jalangi 2 analysis
|
|
||||||
* @author Koushik Sen
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function (sandbox) {
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* This file is a template for writing a custom Jalangi 2 analysis. Simply copy this file and rewrite the
|
|
||||||
* callbacks that you need to implement in your analysis. Other callbacks should be removed from the file.
|
|
||||||
*</p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* In the following methods (also called as callbacks) one can choose to not return anything.
|
|
||||||
* If all of the callbacks return nothing, we get a passive analysis where the
|
|
||||||
* concrete execution happens unmodified and callbacks can be used to observe the execution.
|
|
||||||
* One can choose to return suitable objects with specified properties in some callbacks
|
|
||||||
* to modify the behavior of the concrete execution. For example, one could set the skip
|
|
||||||
* property of the object returned from {@link MyAnalysis#putFieldPre} to true to skip the actual putField operation.
|
|
||||||
* Similarly, one could set the result field of the object returned from a {@link MyAnalysis#write} callback
|
|
||||||
* to modify the value that is actually written to a variable. The result field of the object
|
|
||||||
* returned from a {@link MyAnalysis#conditional} callback can be suitably set to change the control-flow of the
|
|
||||||
* program execution. In {@link MyAnalysis#functionExit} and {@link MyAnalysis#scriptExit},
|
|
||||||
* one can set the <tt>isBacktrack</tt> property of the returned object to true to reexecute the body of
|
|
||||||
* the function from the beginning. This in conjunction with the ability to change the
|
|
||||||
* control-flow of a program enables us to explore the different paths of a function in
|
|
||||||
* symbolic execution.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* Note that if <tt>process.exit()</tt> is called, then an execution terminates abnormally and a callback to
|
|
||||||
* {@link MyAnalysis#endExecution} will be skipped.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* <p>
|
|
||||||
* An analysis can access the source map, which maps instruction identifiers to source locations,
|
|
||||||
* using the global object stored in <code>J$.smap</code>. Jalangi 2
|
|
||||||
* assigns a unique id, called <code>sid</code>, to each JavaScript
|
|
||||||
* script loaded at runtime. <code>J$.smap</code> maps each <code>sid</code> to an object, say
|
|
||||||
* <code>iids</code>, containing source map information for the script whose id is <code>sid</code>.
|
|
||||||
* <code>iids</code> has the following properties: <code>"originalCodeFileName"</code> (stores the path of the original
|
|
||||||
* script file), <code>"instrumentedCodeFileName"</code> (stores the path of the instrumented script file),
|
|
||||||
* <code>"url"</code> (is optional and stores the URL of the script if it is set during instrumentation
|
|
||||||
* using the --url option),
|
|
||||||
* <code>"evalSid"</code> (stores the sid of the script in which the eval is called in case the current script comes from
|
|
||||||
* an <code>eval</code> function call),
|
|
||||||
* <code>"evalIid"</code> (iid of the <code>eval</code> function call in case the current script comes from an
|
|
||||||
* <code>eval</code> function call), <code>"nBranches"</code> (the number of conditional statements
|
|
||||||
* in the script),
|
|
||||||
* and <code>"code"</code> (a string denoting the original script code if the code is instrumented with the
|
|
||||||
* --inlineSource option).
|
|
||||||
* <code>iids</code> also maps each <code>iid</code> (which stands for instruction id, an unique id assigned
|
|
||||||
* to each callback function inserted by Jalangi2) to an array containing
|
|
||||||
* <code>[beginLineNumber, beginColumnNumber, endLineNumber, endColumnNumber]</code>. The mapping from iids
|
|
||||||
* to arrays is only available if the code is instrumented with
|
|
||||||
* the --inlineIID option.
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* In each callback described below, <code>iid</code> denotes the unique static instruction id of the callback in the script.
|
|
||||||
* Two callback functions inserted in two different scripts may have the same iid. In a callback function, one can access
|
|
||||||
* the current script id using <code>J$.sid</code>. One can call <code>J$.getGlobalIID(iid)</code> to get a string, called
|
|
||||||
* <code>giid</code>, that statically identifies the
|
|
||||||
* callback throughout the program. <code>J$.getGlobalIID(iid)</code> returns the string <code>J$.sid+":"+iid</code>.
|
|
||||||
* <code>J$.iidToLocation(giid)</code> returns a string
|
|
||||||
* containing the original script file path, begin and end line numbers and column numbers of the code snippet
|
|
||||||
* for which the callback with <code>giid</code> was inserted.
|
|
||||||
*
|
|
||||||
* </p>
|
|
||||||
* <p>
|
|
||||||
* A number of sample analyses can be found at {@link ../src/js/sample_analyses/}. Refer to {@link ../README.md} for instructions
|
|
||||||
* on running an analysis.
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @global
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
function MyAnalysis() {
|
|
||||||
/**
|
|
||||||
* This callback is called before a function, method, or constructor invocation.
|
|
||||||
* Note that a method invocation also triggers a {@link MyAnalysis#getFieldPre} and a
|
|
||||||
* {@link MyAnalysis#getField} callbacks.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* y.f(a, b, c)
|
|
||||||
*
|
|
||||||
* // the above call roughly gets instrumented as follows:
|
|
||||||
*
|
|
||||||
* var skip = false;
|
|
||||||
* var aret = analysis.invokeFunPre(113, f, y, [a, b, c], false, true);
|
|
||||||
* if (aret) {
|
|
||||||
* f = aret.f;
|
|
||||||
* y = aret.y;
|
|
||||||
* args = aret.args;
|
|
||||||
* skip = aret.skip
|
|
||||||
* }
|
|
||||||
* if (!skip) {
|
|
||||||
* f.apply(y, args);
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {function} f - The function object that going to be invoked
|
|
||||||
* @param {object} base - The receiver object for the function <tt>f</tt>
|
|
||||||
* @param {Array} args - The array of arguments passed to <tt>f</tt>
|
|
||||||
* @param {boolean} isConstructor - True if <tt>f</tt> is invoked as a constructor
|
|
||||||
* @param {boolean} isMethod - True if <tt>f</tt> is invoked as a method
|
|
||||||
* @param {number} functionIid - The iid (i.e. the unique instruction identifier) where the function was created
|
|
||||||
* @param {number} functionSid - The sid (i.e. the unique script identifier) where the function was created
|
|
||||||
* {@link MyAnalysis#functionEnter} when the function <tt>f</tt> is executed. The <tt>functionIid</tt> can be
|
|
||||||
* treated as the static identifier of the function <tt>f</tt>. Note that a given function code block can
|
|
||||||
* create several function objects, but each such object has a common <tt>functionIid</tt>, which is the iid
|
|
||||||
* that is passed to {@link MyAnalysis#functionEnter} when the function executes.
|
|
||||||
* @returns {{f: function, base: Object, args: Array, skip: boolean}|undefined} - If an object is returned and
|
|
||||||
* the <tt>skip</tt> property of the object is true, then the invocation operation is skipped.
|
|
||||||
* Original <tt>f</tt>, <tt>base</tt>, and <tt>args</tt> are replaced with that from the returned object if
|
|
||||||
* an object is returned.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.invokeFunPre = function (iid, f, base, args, isConstructor, isMethod, functionIid, functionSid) {
|
|
||||||
console.log("Attempting to call xyz")
|
|
||||||
return {f: f, base: base, args: args, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a function, method, or constructor invocation.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* x = y.f(a, b, c)
|
|
||||||
*
|
|
||||||
* // the above call roughly gets instrumented as follows:
|
|
||||||
*
|
|
||||||
* var skip = false;
|
|
||||||
* var aret = analysis.invokeFunPre(113, f, y, [a, b, c], false, true);
|
|
||||||
* if (aret) {
|
|
||||||
* f = aret.f;
|
|
||||||
* y = aret.y;
|
|
||||||
* args = aret.args;
|
|
||||||
* skip = aret.skip
|
|
||||||
* }
|
|
||||||
* if (!skip) {
|
|
||||||
* result =f.apply(y, args);
|
|
||||||
* }
|
|
||||||
* aret = analysis.invokeFun(117, f, y, args, result, false, true);
|
|
||||||
* if (aret) {
|
|
||||||
* x = aret.result
|
|
||||||
* } else {
|
|
||||||
* x = result;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {function} f - The function object that was invoked
|
|
||||||
* @param {*} base - The receiver object for the function <tt>f</tt>
|
|
||||||
* @param {Array} args - The array of arguments passed to <tt>f</tt>
|
|
||||||
* @param {*} result - The value returned by the invocation
|
|
||||||
* @param {boolean} isConstructor - True if <tt>f</tt> is invoked as a constructor
|
|
||||||
* @param {boolean} isMethod - True if <tt>f</tt> is invoked as a method
|
|
||||||
* @param {number} functionIid - The iid (i.e. the unique instruction identifier) where the function was created
|
|
||||||
* @param {number} functionSid - The sid (i.e. the unique script identifier) where the function was created
|
|
||||||
* {@link MyAnalysis#functionEnter} when the function f is executed. <tt>functionIid</tt> can be treated as the
|
|
||||||
* static identifier of the function <tt>f</tt>. Note that a given function code block can create several function
|
|
||||||
* objects, but each such object has a common <tt>functionIid</tt>, which is the iid that is passed to
|
|
||||||
* {@link MyAnalysis#functionEnter} when the function executes.
|
|
||||||
* @returns {{result: *}| undefined} - If an object is returned, the return value of the invoked function is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object. This enables one to change the
|
|
||||||
* value that is returned by the actual function invocation.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.invokeFun = function (iid, f, base, args, result, isConstructor, isMethod, functionIid, functionSid) {
|
|
||||||
return {result: result};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after the creation of a literal. A literal can be a function literal, an object literal,
|
|
||||||
* an array literal, a number, a string, a boolean, a regular expression, null, NaN, Infinity, or undefined.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* x = "Hello"
|
|
||||||
*
|
|
||||||
* // the above call roughly gets instrumented as follows:
|
|
||||||
*
|
|
||||||
* var result = "Hello";
|
|
||||||
* var aret = analysis.literal(201, result, false);
|
|
||||||
* if (aret) {
|
|
||||||
* result = aret.result;
|
|
||||||
* }
|
|
||||||
* x = result;
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} val - The literal value
|
|
||||||
* @param {boolean} hasGetterSetter - True if the literal is an object and the object defines getters and setters
|
|
||||||
* @returns {{result: *} | undefined} - If the function returns an object, then the original literal value is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.literal = function (iid, val, hasGetterSetter) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when a for-in loop is used to iterate the properties of an object.
|
|
||||||
*
|
|
||||||
*@example
|
|
||||||
* for (x in y) { }
|
|
||||||
*
|
|
||||||
* // the above call roughly gets instrumented as follows:
|
|
||||||
*
|
|
||||||
* var aret = analysis.forinObject(iid, y);
|
|
||||||
* if (aret) {
|
|
||||||
* y = aret.result;
|
|
||||||
* }
|
|
||||||
* for (x in y) {}
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} val - Objects whose properties are iterated in a for-in loop.
|
|
||||||
* @returns {{result: *} | undefined} - If the function returns an object, then the original object whose
|
|
||||||
* properties are being iterated is replaced with the value stored in the <tt>result</tt> property of the
|
|
||||||
* returned object.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.forinObject = function (iid, val) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is triggered at the beginning of a scope for every local variable declared in the scope, for
|
|
||||||
* every formal parameter, for every function defined using a function statement, for <tt>arguments</tt>
|
|
||||||
* variable, and for the formal parameter passed in a catch statement.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} name - Name of the variable that is declared
|
|
||||||
* @param {*} val - Initial value of the variable that is declared. Variables can be local variables, function
|
|
||||||
* parameters, catch parameters, <tt>arguments</tt>, or functions defined using function statements. Variables
|
|
||||||
* declared with <tt>var</tt> have <tt>undefined</tt> as initial values and cannot be changed by returning a
|
|
||||||
* different value from this callback. On the beginning of an execution of a function, a <tt>declare</tt>
|
|
||||||
* callback is called on the <tt>arguments</tt> variable.
|
|
||||||
* @param {boolean} isArgument - True if the variable is <tt>arguments</tt> or a formal parameter.
|
|
||||||
* @param {number} argumentIndex - Index of the argument in the function call. Indices start from 0. If the
|
|
||||||
* variable is not a formal parameter, then <tt>argumentIndex</tt> is -1.
|
|
||||||
* @param {boolean} isCatchParam - True if the variable is a parameter of a catch statement.
|
|
||||||
* @returns {{result: *} | undefined} - If the function returns an object, then the original initial value is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object. This does not apply to local
|
|
||||||
* variables declared with <tt>var</tt>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.declare = function (iid, name, val, isArgument, argumentIndex, isCatchParam) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a property of an object is accessed.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} base - Base object
|
|
||||||
* @param {string|*} offset - Property
|
|
||||||
* @param {boolean} isComputed - True if property is accessed using square brackets. For example,
|
|
||||||
* <tt>isComputed</tt> is <tt>true</tt> if the get field operation is <tt>o[p]</tt>, and <tt>false</tt>
|
|
||||||
* if the get field operation is <tt>o.p</tt>
|
|
||||||
* @param {boolean} isOpAssign - True if the operation is of the form <code>o.p op= e</code>
|
|
||||||
* @param {boolean} isMethodCall - True if the get field operation is part of a method call (e.g. <tt>o.p()</tt>)
|
|
||||||
* @returns {{base: *, offset: *, skip: boolean} | undefined} - If an object is returned and the <tt>skip</tt>
|
|
||||||
* property of the object is true, then the get field operation is skipped. Original <tt>base</tt> and
|
|
||||||
* <tt>offset</tt> are replaced with that from the returned object if an object is returned.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.getFieldPre = function (iid, base, offset, isComputed, isOpAssign, isMethodCall) {
|
|
||||||
return {base: base, offset: offset, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a property of an object is accessed.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} base - Base object
|
|
||||||
* @param {string|*} offset - Property
|
|
||||||
* @param {*} val - Value of <code>base[offset]</code>
|
|
||||||
* @param {boolean} isComputed - True if property is accessed using square brackets. For example,
|
|
||||||
* <tt>isComputed</tt> is <tt>true</tt> if the get field operation is <tt>o[p]</tt>, and <tt>false</tt>
|
|
||||||
* if the get field operation is <tt>o.p</tt>
|
|
||||||
* @param {boolean} isOpAssign - True if the operation is of the form <code>o.p op= e</code>
|
|
||||||
* @param {boolean} isMethodCall - True if the get field operation is part of a method call (e.g. <tt>o.p()</tt>)
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the value of the get field operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.getField = function (iid, base, offset, val, isComputed, isOpAssign, isMethodCall) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a property of an object is written.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} base - Base object
|
|
||||||
* @param {*} offset - Property
|
|
||||||
* @param {*} val - Value to be stored in <code>base[offset]</code>
|
|
||||||
* @param {boolean} isComputed - True if property is accessed using square brackets. For example,
|
|
||||||
* <tt>isComputed</tt> is <tt>true</tt> if the get field operation is <tt>o[p]</tt>, and <tt>false</tt>
|
|
||||||
* if the get field operation is <tt>o.p</tt>
|
|
||||||
* @param {boolean} isOpAssign - True if the operation is of the form <code>o.p op= e</code>
|
|
||||||
* @returns {{base: *, offset: *, val: *, skip: boolean} | undefined} - If an object is returned and the <tt>skip</tt>
|
|
||||||
* property is true, then the put field operation is skipped. Original <tt>base</tt>, <tt>offset</tt>, and
|
|
||||||
* <tt>val</tt> are replaced with that from the returned object if an object is returned.
|
|
||||||
*/
|
|
||||||
this.putFieldPre = function (iid, base, offset, val, isComputed, isOpAssign) {
|
|
||||||
return {base: base, offset: offset, val: val, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a property of an object is written.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} base - Base object
|
|
||||||
* @param {*} offset - Property
|
|
||||||
* @param {*} val - Value to be stored in <code>base[offset]</code>
|
|
||||||
* @param {boolean} isComputed - True if property is accessed using square brackets. For example,
|
|
||||||
* <tt>isComputed</tt> is <tt>true</tt> if the get field operation is <tt>o[p]</tt>, and <tt>false</tt>
|
|
||||||
* if the get field operation is <tt>o.p</tt>
|
|
||||||
* @param {boolean} isOpAssign - True if the operation is of the form <code>o.p op= e</code>
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the result of the put field operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.putField = function (iid, base, offset, val, isComputed, isOpAssign) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a variable is read.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} name - Name of the variable being read
|
|
||||||
* @param {*} val - Value read from the variable
|
|
||||||
* @param {boolean} isGlobal - True if the variable is not declared using <tt>var</tt> (e.g. <tt>console</tt>)
|
|
||||||
* @param {boolean} isScriptLocal - True if the variable is declared in the global scope using <tt>var</tt>
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the result of the read operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.read = function (iid, name, val, isGlobal, isScriptLocal) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a variable is written.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} name - Name of the variable being read
|
|
||||||
* @param {*} val - Value to be written to the variable
|
|
||||||
* @param {*} lhs - Value stored in the variable before the write operation
|
|
||||||
* @param {boolean} isGlobal - True if the variable is not declared using <tt>var</tt> (e.g. <tt>console</tt>)
|
|
||||||
* @param {boolean} isScriptLocal - True if the variable is declared in the global scope using <tt>var</tt>
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the result of the write operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.write = function (iid, name, val, lhs, isGlobal, isScriptLocal) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a value is returned from a function using the <tt>return</tt> keyword.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} val - Value to be returned
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the value to be returned is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this._return = function (iid, val) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a value is thrown using the <tt>throw</tt> keyword.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} val - Value to be thrown
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the value to be thrown is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this._throw = function (iid, val) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when a <tt>with</tt> statement is executed
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} val - Value used as an argument to <tt>with</tt>
|
|
||||||
* @returns {{result: *} | undefined} - If an object is returned, the value to be used in <tt>with</tt> is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this._with = function (iid, val) {
|
|
||||||
return {result: val};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before the execution of a function body starts.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {function} f - The function object whose body is about to get executed
|
|
||||||
* @param {*} dis - The value of the <tt>this</tt> variable in the function body
|
|
||||||
* @param {Array} args - List of the arguments with which the function is called
|
|
||||||
* @returns {undefined} - Any return value is ignored
|
|
||||||
*/
|
|
||||||
this.functionEnter = function (iid, f, dis, args) {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when the execution of a function body completes
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} returnVal - The value returned by the function
|
|
||||||
* @param {{exception:*} | undefined} wrappedExceptionVal - If this parameter is an object, the function
|
|
||||||
* execution has thrown an uncaught exception and the exception is being stored in the <tt>exception</tt>
|
|
||||||
* property of the parameter
|
|
||||||
* @returns {{returnVal: *, wrappedExceptionVal: *, isBacktrack: boolean}} If an object is returned, then the
|
|
||||||
* actual <tt>returnVal</tt> and <tt>wrappedExceptionVal.exception</tt> are replaced with that from the
|
|
||||||
* returned object. If an object is returned and the property <tt>isBacktrack</tt> is set, then the control-flow
|
|
||||||
* returns to the beginning of the function body instead of returning to the caller. The property
|
|
||||||
* <tt>isBacktrack</tt> can be set to <tt>true</tt> to repeatedly execute the function body as in MultiSE
|
|
||||||
* symbolic execution.
|
|
||||||
*/
|
|
||||||
this.functionExit = function (iid, returnVal, wrappedExceptionVal) {
|
|
||||||
return {returnVal: returnVal, wrappedExceptionVal: wrappedExceptionVal, isBacktrack: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before the execution of a JavaScript file
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} instrumentedFileName - Name of the instrumented script file
|
|
||||||
* @param {string} originalFileName - Name of the original script file
|
|
||||||
*/
|
|
||||||
this.scriptEnter = function (iid, instrumentedFileName, originalFileName) {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when the execution of a JavaScript file completes
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {{exception:*} | undefined} wrappedExceptionVal - If this parameter is an object, the script
|
|
||||||
* execution has thrown an uncaught exception and the exception is being stored in the <tt>exception</tt>
|
|
||||||
* property of the parameter
|
|
||||||
* @returns {{wrappedExceptionVal: *, isBacktrack: boolean}} - If an object is returned, then the
|
|
||||||
* actual <tt>wrappedExceptionVal.exception</tt> is replaced with that from the
|
|
||||||
* returned object. If an object is returned and the property <tt>isBacktrack</tt> is set, then the control-flow
|
|
||||||
* returns to the beginning of the script body. The property
|
|
||||||
* <tt>isBacktrack</tt> can be set to <tt>true</tt> to repeatedly execute the script body as in MultiSE
|
|
||||||
* symbolic execution.
|
|
||||||
*/
|
|
||||||
this.scriptExit = function (iid, wrappedExceptionVal) {
|
|
||||||
return {wrappedExceptionVal: wrappedExceptionVal, isBacktrack: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a binary operation. Binary operations include +, -, *, /, %, &, |, ^,
|
|
||||||
* <<, >>, >>>, <, >, <=, >=, ==, !=, ===, !==, instanceof, delete, in. No callback for <code>delete x</code>
|
|
||||||
* because this operation cannot be performed reflectively.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} op - Operation to be performed
|
|
||||||
* @param {*} left - Left operand
|
|
||||||
* @param {*} right - Right operand
|
|
||||||
* @param {boolean} isOpAssign - True if the binary operation is part of an expression of the form
|
|
||||||
* <code>x op= e</code>
|
|
||||||
* @param {boolean} isSwitchCaseComparison - True if the binary operation is part of comparing the discriminant
|
|
||||||
* with a consequent in a switch statement.
|
|
||||||
* @param {boolean} isComputed - True if the operation is of the form <code>delete x[p]</code>, and false
|
|
||||||
* otherwise (even if the operation if of the form <code>delete x.p</code>)
|
|
||||||
* @returns {{op: string, left: *, right: *, skip: boolean}|undefined} - If an object is returned and the
|
|
||||||
* <tt>skip</tt> property is true, then the binary operation is skipped. Original <tt>op</tt>, <tt>left</tt>,
|
|
||||||
* and <tt>right</tt> are replaced with that from the returned object if an object is returned.
|
|
||||||
*/
|
|
||||||
this.binaryPre = function (iid, op, left, right, isOpAssign, isSwitchCaseComparison, isComputed) {
|
|
||||||
return {op: op, left: left, right: right, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a binary operation. Binary operations include +, -, *, /, %, &, |, ^,
|
|
||||||
* <<, >>, >>>, <, >, <=, >=, ==, !=, ===, !==, instanceof, delete, in.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} op - Operation to be performed
|
|
||||||
* @param {*} left - Left operand
|
|
||||||
* @param {*} right - Right operand
|
|
||||||
* @param {*} result - The result of the binary operation
|
|
||||||
* @param {boolean} isOpAssign - True if the binary operation is part of an expression of the form
|
|
||||||
* <code>x op= e</code>
|
|
||||||
* @param {boolean} isSwitchCaseComparison - True if the binary operation is part of comparing the discriminant
|
|
||||||
* with a consequent in a switch statement.
|
|
||||||
* @param {boolean} isComputed - True if the operation is of the form <code>delete x[p]</code>, and false
|
|
||||||
* otherwise (even if the operation if of the form <code>delete x.p</code>)
|
|
||||||
* @returns {{result: *}|undefined} - If an object is returned, the result of the binary operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.binary = function (iid, op, left, right, result, isOpAssign, isSwitchCaseComparison, isComputed) {
|
|
||||||
return {result: result};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a unary operation. Unary operations include +, -, ~, !, typeof, void.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} op - Operation to be performed
|
|
||||||
* @param {*} left - Left operand
|
|
||||||
* @returns {{op: *, left: *, skip: boolean} | undefined} If an object is returned and the
|
|
||||||
* <tt>skip</tt> property is true, then the unary operation is skipped. Original <tt>op</tt> and <tt>left</tt>
|
|
||||||
* are replaced with that from the returned object if an object is returned.
|
|
||||||
*/
|
|
||||||
this.unaryPre = function (iid, op, left) {
|
|
||||||
return {op: op, left: left, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a unary operation. Unary operations include +, -, ~, !, typeof, void.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {string} op - Operation to be performed
|
|
||||||
* @param {*} left - Left operand
|
|
||||||
* @param {*} result - The result of the unary operation
|
|
||||||
* @returns {{result: *}|undefined} - If an object is returned, the result of the unary operation is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
this.unary = function (iid, op, left, result) {
|
|
||||||
return {result: result};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a condition check before branching. Branching can happen in various statements
|
|
||||||
* including if-then-else, switch-case, while, for, ||, &&, ?:.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} result - The value of the conditional expression
|
|
||||||
* @returns {{result: *}|undefined} - If an object is returned, the result of the conditional expression is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.conditional = function (iid, result) {
|
|
||||||
return {result: result};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called before a string passed as an argument to eval or Function is instrumented.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} code - Code that is going to get instrumented
|
|
||||||
* @param {boolean} isDirect - true if this is a direct call to eval
|
|
||||||
* @returns {{code: *, skip: boolean}} - If an object is returned and the
|
|
||||||
* <tt>skip</tt> property is true, then the instrumentation of <tt>code</tt> is skipped.
|
|
||||||
* Original <tt>code</tt> is replaced with that from the returned object if an object is returned.
|
|
||||||
*/
|
|
||||||
this.instrumentCodePre = function (iid, code, isDirect) {
|
|
||||||
return {code: code, skip: false};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called after a string passed as an argument to eval or Function is instrumented.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {*} newCode - Instrumented code
|
|
||||||
* @param {Object} newAst - The AST of the instrumented code
|
|
||||||
* @param {boolean} isDirect - true if this is a direct call to eval
|
|
||||||
* @returns {{result: *}|undefined} - If an object is returned, the instrumented code is
|
|
||||||
* replaced with the value stored in the <tt>result</tt> property of the object.
|
|
||||||
*/
|
|
||||||
this.instrumentCode = function (iid, newCode, newAst, isDirect) {
|
|
||||||
return {result: newCode};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when an expression is evaluated and its value is discarded. For example, this
|
|
||||||
* callback is called when an expression statement completes its execution.
|
|
||||||
*
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @returns {undefined} - Any return value is ignored
|
|
||||||
*/
|
|
||||||
this.endExpression = function (iid) {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called when an execution terminates in node.js. In a browser environment, the callback is
|
|
||||||
* called if ChainedAnalyses.js or ChainedAnalysesNoCheck.js is used and Alt-Shift-T is pressed.
|
|
||||||
*
|
|
||||||
* @returns {undefined} - Any return value is ignored
|
|
||||||
*/
|
|
||||||
this.endExecution = function () {
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This callback is called only when instrumented with J$.Config.ENABLE_SAMPLING = true
|
|
||||||
* This callback is called before the body of a function, method, or constructor is executed
|
|
||||||
* if returns true, instrumented function body is executed, else uninstrumented function body is executed
|
|
||||||
* @param {number} iid - Static unique instruction identifier of this callback
|
|
||||||
* @param {function} f - The function whose body is being executed
|
|
||||||
* @param {number} functionIid - The iid (i.e. the unique instruction identifier) where the function was created
|
|
||||||
* @param {number} functionSid - The sid (i.e. the unique script identifier) where the function was created
|
|
||||||
* {@link MyAnalysis#functionEnter} when the function <tt>f</tt> is executed. The <tt>functionIid</tt> can be
|
|
||||||
* treated as the static identifier of the function <tt>f</tt>. Note that a given function code block can
|
|
||||||
* create several function objects, but each such object has a common <tt>functionIid</tt>, which is the iid
|
|
||||||
* that is passed to {@link MyAnalysis#functionEnter} when the function executes.
|
|
||||||
* @returns {boolean} - If true is returned the instrumented function body is executed, otherwise the
|
|
||||||
* uninstrumented function body is executed.
|
|
||||||
*/
|
|
||||||
this.runInstrumentedFunctionBody = function (iid, f, functionIid, functionSid) {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* onReady is useful if your analysis is running on node.js (i.e., via the direct.js or jalangi.js commands)
|
|
||||||
* and needs to complete some asynchronous initialization before the instrumented program starts. In such a
|
|
||||||
* case, once the initialization is complete, invoke the cb function to start execution of the instrumented
|
|
||||||
* program.
|
|
||||||
*
|
|
||||||
* Note that this callback is not useful in the browser, as Jalangi has no control over when the
|
|
||||||
* instrumented program runs there.
|
|
||||||
* @param cb
|
|
||||||
*/
|
|
||||||
this.onReady = function (cb) {
|
|
||||||
cb();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
sandbox.analysis = new MyAnalysis();
|
|
||||||
})(J$);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -2,25 +2,39 @@ import wp from 'webpack';
|
|||||||
import path from 'node:path'
|
import path from 'node:path'
|
||||||
const outputPath = path.resolve('./output/');
|
const outputPath = path.resolve('./output/');
|
||||||
console.log(outputPath);
|
console.log(outputPath);
|
||||||
|
|
||||||
|
const l = 'classnames'
|
||||||
|
const libraryLocation = import.meta.resolve(l);
|
||||||
|
console.log(libraryLocation);
|
||||||
|
|
||||||
|
|
||||||
|
// throw Error("5");
|
||||||
const compiler = wp({
|
const compiler = wp({
|
||||||
entry:'./test_src/arithmetic.cjs',
|
entry:libraryLocation,
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
optimization:{
|
optimization:{
|
||||||
mangleExports: false,
|
mangleExports: false,
|
||||||
avoidEntryIife: true,
|
avoidEntryIife: true,
|
||||||
minimize: false
|
minimize: false
|
||||||
|
|
||||||
},
|
},
|
||||||
|
// experiments:{}
|
||||||
output: {
|
output: {
|
||||||
path: outputPath,
|
path: outputPath,
|
||||||
filename: 'lodash.bundle.js',
|
filename: l+'.bundle.cjs',
|
||||||
scriptType: 'module',
|
clean: true,
|
||||||
|
iife: false,
|
||||||
|
library: {
|
||||||
|
type: 'commonjs2',
|
||||||
|
// name: l
|
||||||
|
}
|
||||||
|
// module: true
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
},(err,stats)=>{
|
},(err,stats)=>{
|
||||||
if (err || stats.hasErrors()) {
|
if (err || stats.hasErrors()) {
|
||||||
console.log(stats.hasErrors())
|
|
||||||
console.log(err?.stack)
|
console.log(err?.stack)
|
||||||
console.log(stats.toJson());
|
console.log(stats?.hasErrors())
|
||||||
|
console.log(stats?.toJson());
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@@ -1,4 +1,10 @@
|
|||||||
module.exports.sum = function sum(a, b) {
|
module.exports.sum = function sum(a, b) {
|
||||||
|
let x = 0;
|
||||||
|
|
||||||
|
for(var c in [1,2,3,4]){
|
||||||
|
x+=c;
|
||||||
|
}
|
||||||
|
|
||||||
return a + b;
|
return a + b;
|
||||||
}
|
}
|
||||||
module.exports.div = function div(a, b) {
|
module.exports.div = function div(a, b) {
|
||||||
|
120
test_src/classnames.bundle.cjs
Normal file
120
test_src/classnames.bundle.cjs
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
/******/ var __webpack_modules__ = ({
|
||||||
|
|
||||||
|
/***/ 485:
|
||||||
|
/***/ ((module, exports) => {
|
||||||
|
|
||||||
|
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
|
||||||
|
Copyright (c) 2018 Jed Watson.
|
||||||
|
Licensed under the MIT License (MIT), see
|
||||||
|
http://jedwatson.github.io/classnames
|
||||||
|
*/
|
||||||
|
/* global define */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var hasOwn = {}.hasOwnProperty;
|
||||||
|
|
||||||
|
function classNames () {
|
||||||
|
var classes = '';
|
||||||
|
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
var arg = arguments[i];
|
||||||
|
if (arg) {
|
||||||
|
classes = appendClass(classes, parseValue(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseValue (arg) {
|
||||||
|
if (typeof arg === 'string' || typeof arg === 'number') {
|
||||||
|
return arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof arg !== 'object') {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(arg)) {
|
||||||
|
return classNames.apply(null, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes('[native code]')) {
|
||||||
|
return arg.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
var classes = '';
|
||||||
|
|
||||||
|
for (var key in arg) {
|
||||||
|
if (hasOwn.call(arg, key) && arg[key]) {
|
||||||
|
classes = appendClass(classes, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendClass (value, newClass) {
|
||||||
|
if (!newClass) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
return value + ' ' + newClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value + newClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( true && module.exports) {
|
||||||
|
classNames.default = classNames;
|
||||||
|
module.exports = classNames;
|
||||||
|
} else if (true) {
|
||||||
|
// register as 'classnames', consistent with npm package name
|
||||||
|
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
|
||||||
|
return classNames;
|
||||||
|
}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
|
||||||
|
__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
|
||||||
|
} else // removed by dead control flow
|
||||||
|
{}
|
||||||
|
}());
|
||||||
|
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
/******/ });
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/ if (cachedModule !== undefined) {
|
||||||
|
/******/ return cachedModule.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/
|
||||||
|
/******/ // startup
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__(485);
|
||||||
|
/******/ module.exports = __webpack_exports__;
|
||||||
|
/******/
|
@@ -1,9 +1,10 @@
|
|||||||
var {existsSync,readFile} = require('node:fs');
|
var {existsSync,readFile} = require('node:fs');
|
||||||
// const {cwd} = require('process');
|
// const {cwd} = require('process');
|
||||||
var _var = require('process');
|
var _var = require('process');
|
||||||
var {sum, div} = require('./arithmetic.cjs');
|
var {sum, div,sad} = require('./arithmetic.cjs');
|
||||||
var {sum, div} = require('../output/lodash.bundle.js');
|
// var {sum, div} = require('../output/lodash.bundle.js');
|
||||||
var {ceil} = require('./lodash.js')
|
// var {ceil} = require('./lodash.js')
|
||||||
|
var cn = require('./classnames.bundle.cjs')
|
||||||
let cwd = process.cwd;
|
let cwd = process.cwd;
|
||||||
console.log('a')
|
console.log('a')
|
||||||
|
|
||||||
@@ -20,5 +21,6 @@ console.log(`Read some data`,newLocal,sum(2,34));
|
|||||||
console.log(`Read some data`,newLocal,
|
console.log(`Read some data`,newLocal,
|
||||||
div(7,0),
|
div(7,0),
|
||||||
div(32,3),
|
div(32,3),
|
||||||
ceil(10.24)
|
// ceil(10.24),
|
||||||
|
cn('fooo','foobar')
|
||||||
);
|
);
|
12
todo
12
todo
@@ -1,2 +1,14 @@
|
|||||||
Handle aliasing as a important piece in draft
|
Handle aliasing as a important piece in draft
|
||||||
Please note down problem exploration
|
Please note down problem exploration
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
###
|
||||||
|
My single lib analysis.
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] Scan a library. Get its dependencies.
|
||||||
|
- [ ] Call for its dependencies. Proxy it.
|
Reference in New Issue
Block a user