Skip to content

Is there any way to get the callback of the AssemblyScipt object being destructor? #2048

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
LukiYLS opened this issue Sep 3, 2021 · 7 comments

Comments

@LukiYLS
Copy link

LukiYLS commented Sep 3, 2021

My requirement is this, AssemblyScirpt compiled by Wasm will bridge to the new C++ objects, so I need to notify C++ to release the objects created by C++ when the AssemblyScirpt object is released.

@LukiYLS
Copy link
Author

LukiYLS commented Sep 3, 2021

As mentioned by #383

@dcodeIO
Copy link
Member

dcodeIO commented Sep 3, 2021

There is a rough mechanism in place that is meant as the internal stepping stone to eventually implement FinalizationRegistry. While unsafe and not yet convenient, a global __finalize function can be provided that is called with an object's pointer when it is collected. Here's the respective test case to get an idea how implementing it manually for now could look:

var expect: usize = 0;
var ran = false;
// @ts-ignore
@global function __finalize(ptr: usize): void {
assert(ptr == expect);
ran = true;
}
class Ref {}
expect = changetype<usize>(new Ref());
__collect();
assert(ran);

@LukiYLS
Copy link
Author

LukiYLS commented Sep 9, 2021

There is a rough mechanism in place that is meant as the internal stepping stone to eventually implement FinalizationRegistry. While unsafe and not yet convenient, a global __finalize function can be provided that is called with an object's pointer when it is collected. Here's the respective test case to get an idea how implementing it manually for now could look:

var expect: usize = 0;
var ran = false;
// @ts-ignore
@global function __finalize(ptr: usize): void {
assert(ptr == expect);
ran = true;
}
class Ref {}
expect = changetype<usize>(new Ref());
__collect();
assert(ran);

I found a problem, the ptr changes every time after resize

how to solve this problem?

@dcodeIO
Copy link
Member

dcodeIO commented Sep 9, 2021

From the mention of "resize" I assume that these are the backing buffers of the respective arrays. When resized, a new backing buffer is allocated and the old one is left for the GC. The array object itself remains if it is still referenced, it's just the buffers.

@LukiYLS
Copy link
Author

LukiYLS commented Sep 9, 2021

After memory.grow, I can find the object through changetype in the __finalize function, and then call the object's destructor function

// @ts-ignore 
 @global function __finalize(ptr: usize): void { 
   let object = changetype<Object>(ptr)
   object.finalize()
 } 

In this way, I find that sometimes an exception is thrown

@dcodeIO
Copy link
Member

dcodeIO commented Sep 9, 2021

Not every ptr free'd is an Object. Looking at the class id might help:

import { OBJECT, TOTAL_OVERHEAD } from "rt/common";

@global function __finalize(ptr: usize): void { 
  var obj = changetype<OBJECT>(ptr - TOTAL_OVERHEAD)
  if (obj.rtId == idof<Object>()) {
    ...
  }
}

@github-actions
Copy link

github-actions bot commented Oct 9, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in one week if no further activity occurs. Thank you for your contributions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants