Windows 8 Metro/WinRT能否使用新的JIT编程语言?

20

假设我想创建一种新的编程语言或使用一些不被MS(如Haskell、Java等)支持的语言,但想要能够针对windows 8 metro/winRT进行编码。

我知道Metro UI中的所有应用程序都是沙盒化的。
我知道可以使用本机C++进行编程,因此我认为也可以使用C或汇编语言进行编程。
但是:

  1. 是否可能创建一个类似CLR JIT的JIT,动态生成代码(比如汇编代码),而不会打破沙盒限制?
  2. 假设我只使用在Metro沙盒中允许的API,是否可能不使用XAML作为UI界面?- 我能直接使用Direct2D/DirectX吗?
5个回答

14
据我所知,现在还为时过早,无法做出这个判断。我个人不知道如何编写抖动程序而不使用VirtualProtect(),这是一个核心WinAPI函数,它允许您将由抖动生成的机器码转换为可执行代码的内存块。

对于WinRT应用程序,有许多本地WinAPI函数可供使用。祝福的系统函数列表在此处可用。与内存相关的API非常有限,列表中只有VirtualQuery接近。

那么当前的语言预测是如何实现的呢?让我们来看一下。CLR有一个预测,它加载到您在像C#这样的托管语言中编写的任何Metro应用程序中。在c:\windows\microsoft.net\framework\v4.0.30319\clr.dll上运行dumpbin.exe /imports会生成对Windows DLL的依赖项的相当大的列表。其中一段摘录:

Dump of file clr.dll

File Type: DLL

  Section contains the following imports:

    KERNEL32.dll
...

              430 RaiseException
              581 VirtualAlloc
              584 VirtualFree
              589 VirtualQuery
              587 VirtualProtect          <=== here!
              339 HeapDestroy
              336 HeapAlloc
              342 HeapValidate
              540 SleepEx
              547 SwitchToThread
              ... etc

另一种语言投影是针对JavaScript的,实现在“Chakra”引擎中。很难确定哪个DLL实现了该引擎,这只是一个代码名称。启用非托管调试并运行一个示例JavaScript项目会显示加载了“jscript9.dll”。让我们对其执行dumpbin.exe /imports命令:

  ....
  6898F4D5    10D DebugBreak
  6891FDA1    55E TerminateProcess
  6898EF9E    57E UnhandledExceptionFilter
  6891FD58    43C RaiseException
  68903BB7    59E VirtualProtect                 <=== here!
  6A218590    366 InterlockedPushEntrySList
  6A2185A9    365 InterlockedPopEntrySList
  6A2195AA    35C InitializeSListHead
  689026F9    598 VirtualAlloc
  68902852    59B VirtualFree
  6890603E    4A2 ResetWriteWatch
  ...etc

好的,它在那里。必须得有。问题是,现在你不能调用这个函数。它肯定无法通过商店验证器的审核。

这需要静待至少到真正的WinRT可用,即运行在ARM核心上的WinRT,而不仅仅是运行在Windows 8 Consumer Preview中的Win32上的WinRT。并且可以方便地利用现有的winapi函数,而不仅仅是缩减的列表。这可能会在今年年底左右出现。真正的硬件要到明年夏天才能到你手中。


2
WinRT 在这里几乎充当一个沙盒,因此对 VirtualAlloc / VirtualProtect 的 API 访问不会改变,因为该 API 已经准备好供 OEM 使用。基本上,除了 .NET CLR/JIT(和所有可以被 JIT 编译的动态 .NET 语言)之外,将没有其他方法实现 JIT。 - xoofx
1
当我谈论WinRT时,我指的是整个“WinRT生态系统”,这意味着纯粹的“WinRT”+Win32/COM授权API。Windows 8 Metro应用程序的受限Win32/COM API几乎像沙盒一样运作。因此,没有办法使PE部分可读+可写+可执行,因此也没有JIT。这是Windows 8 Metro目前的设计,我非常怀疑在发布预览版前1个月会更改这种设计。 - xoofx
使用HEAP_CREATE_ENABLE_EXECUTE参数创建HeapCreate堆? - Dwayne Robinson

8
是的,可以为其他编程语言编写WinRT的投影。甚至鼓励这样做。本月早些时候,微软校园举行了一次名为Lang.Next的会议,主题是语言设计。其中一个专题讨论了这个话题,您可能希望观看(我已经观看过):http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/The-Windows-Runtime 并阅读页面上的评论。让我引用其中一条评论:
“Martyn明确表示,我们不仅希望语言设计者和实现者将WinRT添加到其语言和工具链的目标平台列表中,而且我们还将提供帮助和建议。”
所以开始吧! :-)

7

感谢您发布答案!请务必仔细阅读有关自我推广的FAQ。还请注意,每次链接到您自己的网站/产品时,必须发布免责声明。 - Andrew Barber

6

1) 除了可以访问某些受限API(并且可能能够集成它们的JIT,但据我所知,浏览器授权API尚未发布),标准Win8 Metro应用程序将无法访问诸如“VirtualAlloc / VirtualProtect”之类的函数(用于创建/更改读取/写入/可执行内存页面):这意味着在Windows 8 Metro应用程序中开发的C++ JIT不会通过认证。您已经可以使用Visual Studio 11 Beta提供的认证工具包检查您的应用程序。

有人可能会说“我将黑客PE部分以强制读取+写入+可执行”部分,而无需使用VirtualAlloc / VirtualProtect函数,但不幸的是,这种黑客也不起作用,因为您被强制编译Windows 8 Metro exe时选项/NXCOMPAT:YES,这意味着它启用了“数据执行预防”(DEP)。

另一个人可能会尝试动态生成DLL并使用新的“LoadPackagedLibrary”从磁盘加载它们,但是如果DLL不是最初部署的一部分,则实际上锁定了此功能(实际上,我无法使其正常工作)

唯一可用的JIT是.NET JIT。所有使用DLR(动态语言运行时)或反射Emit的.NET动态语言,如IronPython/IronRuby(如果它们针对Win8 Metro进行了更新),都将被JIT编译。因此,如果您的目标是.NET CLR字节码,则可以使您的代码被JIT编译。
例如,能够在.NET CLR中运行Java代码的IKVM.Net可能能够在Windows 8 Metro应用程序下运行(前提是它将被重构为仅使用经过认证的Win8 Metro API)。
2)是的,可以编写不使用XAML的Direct2D/Direct3D11应用程序。
请查看Windows 8 Metro示例http://code.msdn.microsoft.com/windowsapps/Windows-8-Modern-Style-App-Samples。例如,大多数Direct2D示例都没有使用XAML。
CoreWindow类是Metro Window系统的较低级别API,是纯Direct2D/Direct3D11应用程序的入口点。

DEP是否真的可以防止从明确标记为可执行的内存中执行代码?据我所知,正常的代码部分仍然是可执行的。 - Alex Jasmin

0
值得注意的是,即使您成功地使用CLR字节码而不是本机机器代码发出JIT,或者甚至只是实现了一个没有JIT的解释器,您也只能运行包含在原始应用程序包中的代码。如果您从应用程序外部下载脚本/字节码等并尝试在“本地上下文”(即直接访问WinRT库)中运行/JIT/解释它,您将(可能有例外-请参见下面的说明)违反应用程序认证要求第3.9节:

3.9所有应用程序逻辑必须源自并驻留在您的应用程序包中,您的应用程序不得尝试通过任何形式的动态包含代码或数据来更改或扩展打包内容,这会改变应用程序与Windows Runtime的交互方式,或者行为符合Store策略。例如,不允许下载远程脚本并随后在您的应用程序包的本地环境中执行该脚本。

这里的问题在于"本地上下文"的措辞。不清楚它确切的含义是什么。例如,如果您有一个打开网站的门户的Web浏览器控件(或运行在"Web上下文"中的HTML应用程序中的iframe),那么该Web浏览器/iframe会"运行"JIT编译的JavaScript代码,但它将在不同的"上下文"中运行,并且无法直接访问WinRT API。目前尚不清楚此异常是否仅适用于XAML中的IE浏览器控件或具有Web上下文的HTML应用程序中的iframe,或者您是否可以在解释器或动态运行时中实现自己的"Web上下文"。

话虽如此,您可以预先编译任何类型的应用程序代码以将其作为一种方式放入应用程序并获得认证,这与iOS上的操作方式类似,只是您可以选择预编译为.NET、本机机器码或JavaScript。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接