为什么以下C#方法的X86 CallViaStruct
包含cmp
指令?
struct Struct {
public void NoOp() { }
}
struct StructDisptach {
Struct m_struct;
[MethodImpl(MethodImplOptions.NoInlining)]
public void CallViaStruct() {
m_struct.NoOp();
//push ebp
//mov ebp,esp
//cmp byte ptr [ecx],al
//pop ebp
//ret
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个更完整的程序,可以使用各种(发布)解压缩作为注释进行编译.我期望CallViaStruct
两者ClassDispatch
和StructDispatch
类型中的X86 相同但是StructDispatch
(上面提取的)中的版本包括cmp
指令而另一个没有.
看来该cmp
指令是一个成语用于确保变量不为空; 取消引用值为0的寄存器会触发一个av
转为a的寄存器NullReferenceException
.然而,在StructDisptach.CallViaStruct
我ecx
指向一个结构时,我无法设想为null 的方法.
更新:我希望接受的答案将包括StructDisptach.CallViaStruct
通过使其cmp
指令取消引用归零ecx
寄存器而导致NRE被抛出的代码.请注意,CallViaClass
通过设置m_class = null
和无法执行任何一种方法都很容易,ClassDisptach.CallViaStruct
因为没有cmp
指令. …
是否有更美妙的方式来表达一个匿名类(?)与typeScript中的类型成员比这个?
class Foo {
member = {
aNumber = <number>undefined;
aBoolean = <bool>undefined;
}
}
Run Code Online (Sandbox Code Playgroud) 救命!我在C#编程很长一段时间后学会喜欢Javascript,但我学会爱上可迭代协议!
为什么Javascript采用需要为每次迭代创建新对象的协议?为什么要next()
返回一个新的对象具有属性done
和value
代替采用类似C#这样的协议IEnumerable
以及IEnumerator
其在需要两个电话的费用不分配对象(一到moveNext
,看看是否迭代完成,第二,以current
获取价值)?
是否存在漏洞优化,跳过对象返回的分配next()
?很难想象,假设迭代不知道一旦返回就可以使用该对象......
生成器似乎没有重用下一个对象,如下所示:
function* generator() {
yield 0;
yield 1;
}
var iterator = generator();
var result0 = iterator.next();
var result1 = iterator.next();
console.log(result0.value) // 0
console.log(result1.value) // 1
Run Code Online (Sandbox Code Playgroud)
嗯,这是一个线索(感谢Bergi!):
我们稍后将回答一个重要问题(在第3.2节中):为什么迭代器(可选)在最后一个元素之后返回一个值?这种能力是元素被包裹的原因.否则,迭代器可以简单地在最后一个元素之后返回一个公开定义的sentinel(停止值).
并在Sect.3.2他们讨论使用Using generator作为轻量级线程.似乎说返回一个对象的原因next
是,value
即使done
是,也可以返回true
!哇.此外,可以生成return
除了值yield
和yield*
-ing值和一个值,生成由return
作为最终value
时done
是true
!
所有这些都允许伪线程.而这个功能,伪线程,值得为循环中的每一次分配一个新对象... Javascript.总是如此意外! …
javascript performance memory-management iterable ecmascript-6