Error in web worker using web assembly - javascript

I would like to use WebAssembly within a web worker.
From my main application, I launch it like this:
let w = new Worker('test.js');
w.onmessage = (event) => { console.log(event); };
w.onerror = (event) => { console.error(event); };
w.postMessage({ message: "Hello World" });
Then, I created a file test.js as follows:
self.Module = {
locateFile: function (s) {
console.log(s);
return s;
}
};
self.importScripts("main.js");
// note: `main.js` is the JavaScript glue file created by emcc
self.onmessage = function(messageEvent) {
console.log(messageEvent); // works!
console.log(self.Module); // works!
console.log(self.Module.ccall("test")); // crashes!
}
I get an error: Uncaught TypeError: Cannot read property 'apply' of undefined. I don't understand why self.Module is undefined, how is that possible?
I have the feeling there is something about the scope of the web worker and WebAssembly that does not work well together.
Thanks for your input!

The problem is that console.log() does not reveal the true state of the object at execution time. Further digging revealed that in fact the object Module was not ready yet.
I cite from: https://kripken.github.io/emscripten-site/docs/getting_started/FAQ.html
How can I tell when the page is fully loaded and it is safe to call compiled functions?
Calling a compiled function before a page has fully loaded can result
in an error, if the function relies on files that may not be present
[...]
Another option is to define an
onRuntimeInitialized function:
Module['onRuntimeInitialized'] = function() { ... };
That method will be called when the runtime is ready and it is ok for you to call compiled code.
Adjusting my test.js (worker) file fixes the issue:
self.Module = {
locateFile: function (s) {
console.log(s);
return s;
}
// Add this function
onRuntimeInitialized: function() {
test();
}
};
self.importScripts("main.js");
// note: `main.js` is the JavaScript glue file created by emcc
self.data = {};
// to pass data from the main JS file
self.onmessage = function(messageEvent) {
console.log(messageEvent); // works!
self.data = messageEvent; // save the data
}
// gets executed when everything is ready.
self.test = function() {
// we may safely use self.data and self.Module now!
console.log(self.Module.ccall("test")); // works!
}

Related

jQuery noop causing JS minify to remove code in .NET Framework 4.8 web app

When I publish my .NET app, one of my JS files doesn't minify correctly. I have several hundred lines of code in the file but end up with a near empty function after the process has completed. I have gone through it and determined it is down to a $.noop that I use, without it the process works fine. To demonstrate this I have broken it down into a simple example that shows how it affects the file.
var MyApp = {};
MyApp.EmailPopup = (function () {
function Test() {
// do lots of jquery stuff
alert('hi');
}
var thisObject = {
Show: $.noop
};
thisObject.Show = function () {
Test();
};
return thisObject;
})();
When minified the call to Test is removed as shown:
var MyApp={};MyApp.EmailPopup=function(){return{Show:$.noop}}();
However if I remove the $.noop function and add an empty function instead like so:
var MyApp = {};
MyApp.EmailPopup = (function () {
function Test() {
// do lots of jquery stuff
alert('hi');
}
var thisObject = {
Show: function () { } // this has changed
};
thisObject.Show = function () {
Test();
};
return thisObject;
})();
Then I get the desired minified version:
var MyApp={};MyApp.EmailPopup=function(){return{Show:function(){alert("hi")}}}();
In the real app, by it not including the equivalent Test function I am losing hundreds of lines of code. Can someone explain why using $.noop prevents it from working, but initialising to an empty function or null works? It is a .NET 4.8 web application, it uses jQuery 3.3.1 and I build it with Visual Studio 2019.

'TypeError: is not a function' in Node.js

I'm getting the error while running the following code in Node.js
var assert = require('assert');
var request = require('request');
var index = require('./index');
it('verify javascript function', function(done) {
var v2 = index.AddNumbers(5, 6);
assert.equal(11, v2);
done();
});
The index.js file contain the following code:
function AddNumbers(a,b){
return a+b;
}
What am I doing wrong?
This happened to me many times because of circular dependency, check if you have 2 classes that are requiring each other, remove one of them from requiring the other and the issue should be solved
With NodeJS modules, to make something public, you have to export it. Add this to the end of index.js:
module.exports.AddNumbers = AddNumbers;
(That's using the old CommonJS modules. For ESM, it would be export AddNumbers;)
Here it is running on my machine:
$ cat index.js
function AddNumbers(a,b){
return a+b;
}
module.exports.AddNumbers = AddNumbers;
$ cat example.js
var index = require('./index');
var v2 = index.AddNumbers(5,6);
console.log(v2);
$ node example.js
11
I'm fairly a beginner at Node JS so I managed to get this error by importing a function like so:
const { functionName } = require('./function')
instead of like so:
const functionName = require('./function')
Editing my post to add an explanation since I've learned more node since I wrote it. If a module exports an object containing multiple functions functions like so:
module.exports = { functionName, otherFunction }
Then the function has to be deconstructed out of the object during the import, as in the first code snippet. If the module exports a single function or a default function, like so:
module.exports = functionName
Then tt must be imported directly, as in the second code snippet.
If you need to expose a specific component, function or a variable to public. You have to exports those components using JavaScript modules.
let add = (a,b)=>{
return ( a+b);
}
module.exports.add=add;
or if you want to expose multiple functions, you can do as follows.
let add = (a,b)=>{
return (a+b);
}
let subtract = (a, b)=>{
return (a-b);
}
module.exports={
add : add,
subtract : subtract
};
This is happening because two files are referencing each other i.e You are calling function (s) from file A in file B and vice versa which is called Circular Dependency.
Your "AddNumbers" function in the "index.js" file should be as follows,
function AddNumbers(a,b){
var addition = function(a, b){
return (a + b) ;
};
module.exports = {
additionResult: addition
};
}
And you need to call it in your "Node.js" file as follows
var assert = require('assert');
var request = require('request');
var index = require('./index');
it('verify javascript function', function(done) {
var v2 = index.additionResult(5, 6);
assert.equal(11, v2);
done();
});
This should work. Please note that you call the function by whatever the token name you exported the return value by (I use a different name here just for clarity). Almost everybody uses the same name as the function name so there are no confusion. Also in ES6, if you use the same name you can export as just,
module.exports = {
addition
};
instead of,
module.exports = {
addition: addition
};
since you use the same name. It is an ES6 feature.
I ran into the same problem while trying to follow a Nodejs tutorial by w3schools.
I copied the following code from them:
exports.myDateTime = function () {
return Date();
};
That, however, wouldn't work for me. What resolved the problem for me was adding module. before the exports keyword like this:
module.exports.myDateTime = function () {
return Date();
};
The most correct answer was from #shimi_tap. I want to reply it as comment, but doesn't have enough reputation, so I am gonna answer it using a simple example, like in this case below:
File A has 3 functions to process database activity: function
addDB, updateDB, and delData;
File B has 2 functions to process User activity on smartphone:
function addHistory, and editHistory;
Function updateDB in file A is calling function editHis in file B, and function editHistory is calling function updateDB in file A. This is what we called circular-dependency. And we need to prevent it by only giving output of state from editHistory and the rest will be processed inside file A.
//ORIGINAL FUNCTIONS which caused CIRCULAR DEPENDENCY
function updateDB() {
//process update function here
//call function in fileB
const history = require("fileB.js");
await history.editHistory(data).then((output) => {
if(output["message"] === "success"){
response = {
state: 1,
message: "success",
};
}
});
return response;
}
//THIS is the WRONG ONE
function editHistory() {
//process function to edit History here
//call function in fileA
const file = require("fileA.js");
await file.updateDB(data).then((output) => { //You should not call it here
if(output["message"] === "success") {
output = {
state: 1,
message: "success",
};
}
});
return output;
}
//==================================================//
//THE FIX
function updateDB() {
//process function here
const history = require("fileB.js");
await history.editHistory(data).then((output) => {
if(output["message"] === "success"){
await updateDB(data).then((output) => {
response = {
state: 1,
message: "success",
};
});
} else {
log("Error");
}
});
return response;
}
function editHistory() {
//process function to edit History here
// No more calling to function inside the file A
output = {
state: 1,
message: "success",
};
return output;
}
https://medium.com/visual-development/how-to-fix-nasty-circular-dependency-issues-once-and-for-all-in-javascript-typescript-a04c987cf0de
this post visualizes the circular dependency injection
like a child or nested file tried to import parent or top-level file
repo.js
service.js
there are 2 files
service.js uses repo.js file by importing
it works
but check in repo.js that it tried to import service.js file
it shows circular dependency injection warning
In my case the problem was the missing semicolon at the end of the lines.
const codec = JSONCodec()
(async () => {
for await (const message of subscription) {
const payload = codec.decode(message.data)
stompServer.send('/topic/update-event', {}, payload)
}
})()
This produced the following error:
TypeError: JSONCodec(...) is not a function
I was so used to writing code without semicolons, which led me to this problem with the bare NodeJs. As soon as I had put the semicolons, the problem disappeared.
A simple way I debugged this (After about 2 days of troubleshooting) was to actually see why 'x' is not a function. Basically, console.log(x) to see the actual object returned. Turned out I was conflicting x with another declared variable (happens especially when you use axios.res and req,res args.
Require the other file in function level.
fileOne.js
function main() {
const fileTwo = require('./fileTwo');
console.log("hello from file one");
}
module.exports = main;
main();
fileTwo.js
function main() {
const fileOne = require('./fileOne');
console.log("hello from file two");
}
module.exports = main;
main();
Now execute > node fileOne.js
Output:
hello from file two
hello from file one
One silly mistake I did was while exporting was:
module.exports = [module_name_1, module_name_2, ..., module_name_n]
The right way is:
module.exports = {module_name_1, module_name_2, ..., module_name_n}

Access extension's functions from webpage in Firefox

I'm trying to write an extension to Firefox that would allow me to access internal functions/classes/objects of it from my webpage. I want them to be visible and accesible in DOM. It worked when extension was loaded as a component from chrome.manifest file but it doesn't seem that it's possible in e10s (multiprocess Firefox) anymore.
So I was trying and trying and the best option I have found so far seems to be using exportFunction, createObjectIn and cloneInto functions. They work fine when expected to make objects visible from pages loaded by the extension itself but not from remote ones.
I'm using Addon-SDK now and my code is
And then
function injectTest(event) {
let domWindow = event.subject;
//This creates and object that is always visible but never accesible from page not loaded by the extension
foo = Cu.createObjectIn(domWindow.wrappedJSObject, {defineAs: "testSDK"});
//This exports my function fine but I can export it only into an existing object
//That's why I'm using "crypto" here
Cu.exportFunction(test.bind(this, domWindow),
domWindow.crypto.wrappedJSObject,
{ defineAs: "test" });
//This exports my function to my object but only on pages loaded by the extension
Cu.exportFunction(test.bind(this, domWindow),
foo,
{ defineAs: "test2" });
//Same here, cloned_var seems to be not accesible from remote webpage
var to_be_cloned = {"greet" : "hey"};
foo.cloned_var = Cu.cloneInto(to_be_cloned, foo);
}
exports.main = function(options, callbacks) {
if (!gInitialized &&
(options.loadReason == "startup" ||
options.loadReason == "install" ||
options.loadReason == "enable")) {
log("initializing - " + options.loadReason);
try {
events.on("content-document-global-created", injectTest);
} catch (error) {
log(error);
}
gInitialized = true;
}
};
I'm totally new to javascript and Firefox extensions so I have no idea how to make it work. What I'm doing wrong? Is there any better idea to access extension's objects?
Thank you in advance for help.
#edit 19.05.15
Tried using page-mod. It does work but not as well as I need.
main.js file
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
pageMod.PageMod({
include: "mywebsite",
contentScriptFile: [data.url("cscript.js")],
contentScript: 'window.alert("Page matches ruleset");'
});
cscript.js file (in data folder)
var contentScriptObject = {
"greeting" : "hello from add-on",
b: 1,
powitaj: function(){
return(this.greeting);
}, //when called from console returns "hello from add-on"
is_b: function(){
if(b){
return true;
}else{
return false;
}
}, //undefined
is_thisb: function(){
if(this.b){
return true;
}else{
return false;
}
}, //returns 1
func: function(){
console.log("ok")
}, //returns "ok"
is_func: function(){
func();
}, //undefined
is_thisfunc:function(){
this.func();
} //undefined
};
So from my website I can access inner variables (actually variables defined globally too and modify them as well), I can access inner functions (not outer - not included in the code) but my inner functions cannot call each other and I'd like to be able to do that.
To run chrome-privileged code in a e10s-content process you'll need framescripts
The SDK has some wrapper modules to simplify the communication and module loading between parent and child process
If you only need exportFunction/cloneInto/createObjectIn then using the page-mod module may be sufficient, if i recall correctly those helpers are made available in its context.

node.js automatic logging with metadata

I want to create a Node.js logged decorator (function filter) that works like this (pseudocode warning):
logged = function(f) {
return function() {
log(f.file, f.line, f.class, f.name, arguments)
return f.call(this, arguments)
}
}
Is there a way of accesing the information above? I'm going to be doing heavy logging, so throwing a fake Exception and reading the trace is probably not viable (or is it?).
Note: by f.class I mean the name of the function that holds the prototype. Also, I'm using coffee-script, in case it matters
You don't have to throw the exception, var stack = new Error().stack is enough. From there it is possible to parse out the file, line number, and the class name. BUT the problem is, that it only tracks the function calls, so now to get the proper information for the decorated function Error should be initialized some where within the function or the class. Doing this in decorator, you can get only the information about the file/linenumber where the decoration of the function was occurred, and not where the function was declared.
function User(){}
User.prototype.foo = function(){};
User.stack_ = function(){
return new Error().stack
};
// ...
function wrapp(Ctor, name){
var stack = Ctor.stack_();
var info = parseStack(stack);
var orig_ = Ctor.prototype[name];
Ctor.prototype[name] = function(){
console.log('Info:', info);
return orig_.apply(this, arguments);
};
}
function parseStack(stack){
// implement better stacktrace parser
return stack.split('\n')[1];
}
// ...
wrapp(User, 'foo');
// ...
var user = new User;
user.foo();
// and you get smth. like
// Info: at Function.User.stack_ (filename:line:column)
I think this is maximum you can get, and you must always define this stack_ function.

Javascript Module Pattern confusion

I am trying to use the Javascript Module pattern. I want my module to have a public method that can be called when a json file is loaded. In this simple example, the module loads the json on init and (should) load an image into a DOM element when the public method 'loadPic' is called. The source of the image is in the json file.) When I run the script the first time, I get the following error: Uncaught TypeError: Cannot read property 'src' of undefined. My interpretation is that the method 'loadPic' is called automatically, before the data is loaded... but I don't know how to prevent that. Here is the code (PS: I am using Zepto, the 'light' version of jQuery):
<!-- language: lang-js -->
/* in module file: DualG.js */
;(function ($) {
$.extend($.fn, {
DualG: function (element, options) {
var defaults = { // not used yet...
indexStart:0,
url: 'js/data.json'
},
my = {},
init,
loadPic,
plugin = this;
plugin.settings = {};
plugin.pics = [];
init = function () {
plugin.settings = $.extend{}, defaults, options);
$.getJSON(plugin.settings.url, function (data) {
var l = data.images.length, i;
for (i = 0; i < l; i = i + 1) {
plugin.pics[data.images[i].index] = data.images[i];
}
});
init();
my.loadPic = function (index, container) {
$(container).empty().append($("<img>").attr({"src":plugin.pics[index].src}));
};
return my;
}
});
}(Zepto));
My problem was that data is loaded a-synchronistically - so I was tying to use data that was not loaded yet. I added an event trigger in the init, after loading the data. Then, I listen to the event and call the loadPic method only then... Thanks all for your help.

Categories