问题标签 [thunk]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
55 浏览

windows - Visual Studio Performance Profiler 输出中的 $$Thunk@ 条目是什么?

我在我的代码上使用了 Visual Studio 2015 性能分析器 (Alt+F2) - 发布版本 x64 EXE,一个使用 SDL 的 GUI 程序。查看初始分析器报告,列表中有许多$$Thunk@条目。

据说所有都来自我的程序模块,但是当我右键单击该View Source选项时显示为灰色。

他们假定的调用者的代码不包含对他们的调用。

这些符号在我通过 运行EXE或PDB时strings -a不会出现,它们不会出现在由 生成的反汇编中dumpbin /disasm,并且我无法在调试器的反汇编窗口中访问它们。

这些条目指的是什么?

0 投票
1 回答
21 浏览

function - 为什么他们称他们为 Thunks?

Thunk 通常被定义为延迟表达式求值的任何代码(通常是函数)。

在 JavaScript 中,Thunk 可能看起来像(a,b)=>a+b,但它们存在于许多不同的语言中。

https://en.wikipedia.org/wiki/Thunk

所以,我的问题是为什么他们称他们为“Thunk”?是有原因还是只是某人选择的随机词。

0 投票
1 回答
620 浏览

c++ - 为什么需要虚拟 thunk?

这个问题是关于虚函数调用的(可能的)实现(我相信它被使用gcc)。

考虑以下场景:

  1. F 类继承自 D 类(可能还有其他),而 D 类继承自 B 类(不是虚拟的)。D 覆盖f()B 中声明的虚方法;实例化一个 F 类型的对象
  2. F 类继承自 D 类(可能还有其他),而 D 类继承自 B 类(虚拟)。D 覆盖f()B 中声明的虚方法;实例化一个 F 类型的对象

(这两种情况的唯一区别是B类的继承方式)

在场景 1 中,在对象 B 的 vtable 中,在目的地的位置f()现在有一个(非虚拟的)thunk 表示:

如果你想打电话f(),首先改变this指针offset

(实际上是 D 把这个 thunk 放在那里)

在场景 2 中,在对象 B 的 vtable 中,在目的地的位置f()现在有一个(虚拟)thunk,它说:

如果要调用f(),首先将this指针更改为存储的值addr

(D无法准确告诉B需要调整多少this指针,因为它不知道B对象在F对象最终内存布局中的位置)

这些假设是通过查看与g++ -fdump-class-hierarchy结合的输出而做出的g++ -S。他们是正确的吗?

现在我的问题是:为什么需要虚拟thunk?为什么 F 不能在 B 的虚拟表中(在 for 的位置)放置一个非虚拟f()thunk ?因为当需要实例化 F 对象时,编译器知道它f()在 B 中声明,但在 D 中被覆盖。它还知道对象 B (-in-F) 和对象 D (-in -F)(我认为这首先是虚拟重击的原因)。

编辑(添加g++ -fdump-class-hierarchy和的输出g++ -S

场景一:

g++ -fdump-class-hierarchy

F 的 Vtable

...

48 (int (*)(...))D:: _ZThn8_N1D1fEv (de-mangled: non-virtual thunk to D::f())

g++ -S

_ZThn8_N1D1fEv

.LFB16:

.cfi_startproc

subq $8, %rdi #,

jmp .LTHUNK0 #

.cfi_endproc

场景二:

g++ -fdump-class-hierarchy

F 的 Vtable

...

64 (int (*)(...))D:: _ZTv0_n24_N1D1fEv (de-mangled: virtual thunk to D::f())

g++ -S

_ZTv0_n24_N1D1fEv

.LFB16:

.cfi_startproc

movq (%rdi), %r10 #,

addq -24(%r10), %rdi #,

jmp .LTHUNK0 #

.cfi_endproc

0 投票
1 回答
309 浏览

c++ - Itanium C++ ABI 主要虚拟基础

我在这里阅读有关如何选择主要碱基的信息:

"...2。如果 C 是动态类类型:

一个。识别所有直接或间接的虚拟基类,它们是某些其他直接或间接基类的主要基类。调用这些间接主要基类。

湾。如果 C 有一个动态基类,则尝试选择一个主基类 B。它是第一个(按直接基类顺序)非虚拟动态基类(如果存在)。否则,它是一个几乎为空的虚拟基类,是(预排序)继承图顺序中的第一个,如果存在的话,它不是间接主基类,或者如果它们都是间接主基类,则只是第一个......”

在进行此更正之后:

“上面的情况(2b)现在被认为是设计上的错误。使用第一个间接主基类作为派生类的主基并没有节省对象的任何空间,并且会造成一些虚函数的重复基类虚拟表的附加副本中的指针。

好处是使用派生类的虚指针作为基类的虚指针通常会节省负载,并且调用它的虚函数不需要对this指针进行调整。

人们认为 2b 将允许编译器在某些情况下避免调整它,但这是不正确的,因为虚函数调用算法要求通过指向定义函数的类的指针来查找函数,而不是仅仅继承它。删除该要求并不是一个好主意,因为这样就不再有办法用它们跳转到的函数来发出所有 thunk。例如,考虑这个例子:

结构 A { 虚拟 void f(); };

结构 B : 虚拟公共 A { int i; };

结构 C : 虚拟公共 A { int j; };

结构 D:公共 B,公共 C {};

当 B 和 C 被声明时,A 是每种情况下的主要基础,因此尽管在 A-in-B 和 A-in-C vtables 中分配了 vcall 偏移量,但不需要进行此调整,也不会生成 thunk。但是,在 D 对象内部,A 不再是 C 的主要基础,因此如果我们允许对 C::f() 的调用使用 C 子对象中 A 的 vtable 副本,我们需要将其从 C* 调整为B::A*,这需要第三方 thunk。因为我们要求对 C::f() 的调用首先转换为 A*,所以 C-in-D 的 A 的 vtable 副本永远不会被引用,所以这不是必需的。”

您能否举个例子解释一下这指的是什么:“删除该要求不是一个好主意,因为这样就不再有一种方法可以使用它们跳转到的函数发出所有 thunk ”?

另外,什么是第三方 thunk

我也不明白引用的示例试图显示什么。

0 投票
2 回答
5057 浏览

javascript - 简单来说,thunk 和高阶函数有什么区别?

我知道两者都是返回函数的函数。

到目前为止,我使用 thunk 的经验是使用它们来返回函数,而不仅仅是操作对象,这样我就可以在Redux.

闭包是高阶函数 (HOF) 的一种实现,目的是为私有变量创建新的作用域……对吧?HOF的其他示例包括map和。reducefilter

还有什么其他东西明确定义了两者之间的区别吗?

谢谢。

0 投票
1 回答
44 浏览

javascript - 使用 thunk 有条件地执行 async 不会执行两次

我正在关注Kyle Simpson Rethinking Asynchronous JavaScript视频课程,并且对他的 thunk 模式如何使用闭包感到困惑。代码是这样的:

th2我在最后的嵌套部分添加了额外的调用。我希望这种闭包的使用能够返回最初打印的值th2,存储在函数的闭包变量textgetFile,即不会进行另一个网络调用。虽然这不是发生的事情:在t3回调中打印文本后执行停止。

为什么这个闭包不返回它已经检索到的值?

0 投票
0 回答
139 浏览

javascript - JavaScript 正确使用 thunk 函数(带变量)

我被困在一个 thunk 函数的使用中,我需要更好地理解它是如何工作的。

不起作用的代码:

有效的代码:

从我“对 JavaScript thunk 不太熟练”的角度来看,两个代码是相同的,但它们并不是只有第二个有效,所以:

a) 为什么代码的行为不一样?为什么将 thunk 内容存储在函数 ( fields) 中会使其行为不同?

b)我的fields变量在代码序列中使用,所以有没有办法让 thunk 工作,将其对象保存在单独的变量中,如代码 1(实际上是对代码 1 的修复,保留field变量)?

0 投票
3 回答
188 浏览

assembly - Pointlessly trying to compare rsp across a call without using registers

I would like to write a small thunk which will call an underlying function and then compare the value of rsp before and after the call. Critically, this code shouldn't clobber any registers.

The obvious implementation is to simply push rsp before the call, and then compare after. The problem is that push rsp itself subtracts 8 from the stack, so you should actually compare the saved value of rsp with the value after the call plus 8.

Here's one way to do it:

The problem is this accesses a value [rsp - 8] which is above rsp - i.e., not on the stack but the nebulous region above the stack. This should be where you have a red-zone, but it isn't when you don't.

What are the alternatives? Performance and code-size is important.

0 投票
1 回答
46 浏览

javascript - 使用 thunk:为什么我的代码没有按顺序打印?

我试图理解 thunks。我正在学习 Kyle Simpson 在 Lynda 上的 Rethinking Async JS 课程。

我有这个代码:

现在,当我执行以下操作时:

结果是 625 打印了两次。

但是,当我执行

结果是 25 执行了两次。

在第一种情况下,我的期望是先打印 625,然后再打印 25。在第二种情况下,先打印 25,然后再打印 625。

为什么我的期望不正确?

0 投票
1 回答
186 浏览

angular - 解析动作创建器中的异步功能

我试图在状态更新之前在我的动作创建者中解决这个异步调用。我试图实现 redux thunk,但我对它和 angular4+ 整体来说还很陌生。

这是我的动作创建者的样子:

thunk 的主要问题是我的服务方法没有在实际的 thunk 中定义。

以下是该服务的基本外观:

我想我的问题真的是如何在 redux 中间件中使用服务方法,或者有其他方法吗?

非常感谢任何帮助。