v8:创建函数时SideEffektType属性的确切含义

时间:2018-10-08 15:15:20

标签: c++ v8

从c ++创建新的Function<T>时,v8要求C回调的SideEffektType

在v8.h中将其描述为Options for marking whether callbacks may trigger JS-observable side effects.。 可观察到的副作用在这里仍然有很多猜测。例如,如果您实现了一个打印到std::cout的函数,则没有JS可观察到的副作用,但是您仍然不希望编译器重新编译或忽略对该函数的调用。

另一个问题是,如果将c对象的getter和setter导出为js函数,如何标记我们的函数。它们确实具有明显的副作用-省略或重新编排可能会破坏语义-但它们不会更改当前的堆栈框架或任何全局变量,从而使v8具有很大的优化潜力。

我们很想知道v8中如何使用此属性,因为这应该有助于回答对每个函数使用哪个标志。

2 个答案:

答案 0 :(得分:0)

好吧,请看SideEffectType枚举的文档:

/**
 * Options for marking whether callbacks may trigger JS-observable side effects.
 * Side-effect-free callbacks are whitelisted during debug evaluation with
 * throwOnSideEffect. It applies when calling a Function, FunctionTemplate,
 * or an Accessor callback. For Interceptors, please see
 * PropertyHandlerFlags's kHasNoSideEffect.
 * Callbacks that only cause side effects to the receiver are whitelisted if
 * invoked on receiver objects that are created within the same debug-evaluate
 * call, as these objects are temporary and the side effect does not escape.
 */

因此,这与优化潜力无关。 (请放心,V8知道读写属性之间的顺序要求;对此不需要特殊的注释。)

因此,换句话说:

  • 如果您有吸气剂(不管它叫多少频率),请标记为kHasNoSideEffect
  • 如果您有一个设置者(通常像设置者那样)写了接收者对象的属性,则将其标记为kHasSideEffectToReceiver
  • 如果您有一个函数执行您不想重复的其他事情(更改全局变量,创建数据库条目等),请将其标记为kHasSideEffect。可以打印到std::cout的函数也可能属于此类别,但是由您决定如何感觉可能向std::cout发送垃圾邮件。如果您不使用调试评估,那么您甚至都不会看到差异。

答案 1 :(得分:0)

v8调试器协议使用这些标志来确定热切评估输入是否安全。

如果确定输入没有副作用,则可以在调试器中按Enter之前显示该输入:

eager evaluation of "1 + 1"

在这里,输入将使a突变,因此会有副作用。如您所见,a.push(2)没有得到评估。

no eager evaluation of "Array.prototype.push"

  

例如,如果您实现一个打印到std :: cout的函数,则没有JS可观察到的副作用,但是您仍然不希望编译器重新编译或忽略对该函数的调用。

这样,您可以自己决定自己认为是什么副作用,而v8会服从您。