Skip to content
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

support ARM mac #303

Closed
pebble8888 opened this issue Jun 25, 2020 · 78 comments
Closed

support ARM mac #303

pebble8888 opened this issue Jun 25, 2020 · 78 comments

Comments

@pebble8888
Copy link
Member

XVim2 has Intel assemby code.

@sobri909
Copy link

I'm about 30 years out of date on ARM assembly 😂 The last time I worked with it was on Acorn. But I'd be happy to contribute towards an Apple Transition Developer Kit!

@pebble8888
Copy link
Member Author

@rudedogg Yes.

@jspavlick
Copy link

Is this still a problem? A friend of mine with one of the developer preview Mac mini's was able to run make and it compiled successfully. However he didn't code sign Xcode so he can't confirm fully if XVim2 runs or not.

@jrsharp
Copy link

jrsharp commented Nov 18, 2020

Yes, this still appears to be an issue. I was able to build XVim2 successfully for Xcode 12.2, but Xcode does not seem to like installing/running Xcode plugins compiled for x86-64 only (using Rosetta2), as XVim2 currently excludes arm64. Initial attempt to build for arm64 failed -- will have to dig into it further.

(This was done on a MacBook Pro 13 w/ Apple M1 on Big Sur 11.0.1)

@jspavlick
Copy link

Is there anyway I can help (maybe by trying to cross-compile)? I have an Intel based MBP running 10.15.7 Catalina.

@jrsharp
Copy link

jrsharp commented Nov 18, 2020

Well, the issue seems to be well understood, as identified above -- replacing the x86 asm in SourceEditorViewWrapper.s. In the short term, Xcode can be forced to be opened using Rosetta2, and I can confirm XVim2 functions when using Rosetta2.

@jspavlick
Copy link

Yeah, I saw the x86 assembly. But I was wondering maybe there is/are other problems in addition to that.

That's good news in terms of a (temporary) workaround. That's enough for me to order an M1 machine.

@rookiezn
Copy link

Yeah, I saw the x86 assembly. But I was wondering maybe there is/are other problems in addition to that.

That's good news in terms of a (temporary) workaround. That's enough for me to order an M1 machine.

@jspavlick What's the workaround to use XVim2 on ARM mac? Thanks.

@jspavlick
Copy link

jspavlick commented Dec 11, 2020

@rookiezn I don't know. I don't have my M1 mac yet. As jrsharp eluded to, if you force Xcode to run using Rosetta2 (it's a universal binary, right? So it will run the x86 version through emulation) then it will work, but presumably everything (compiling etc) will be slower?

@webcpu
Copy link

webcpu commented Dec 12, 2020

There is a workaround. You can run Xcode using rosetta. Xcode is an universal application.

  1. Close Xcode
  2. Go to Applications and right click Xcode.
  3. Click "Get info" menu item in Context menu.
  4. Tick "Open using rosetta"
  5. Run Xcode
    Please notes that please make sure you have installed Xvim2.

It's unfortunately that the performance of Xcode is worse using Rosetta, especially building a big project.

@r-plus
Copy link
Member

r-plus commented Dec 13, 2020

hmm, its assemby code is for call swift only interface (have not @objc attribute) instance method that implemented in xcode from xvim(objc), right?

@webcpu
Copy link

webcpu commented Dec 13, 2020

It's possible to convert Intel assembly to Objective-C/C using decompiler. https://www.hopperapp.com/

@r-plus
Copy link
Member

r-plus commented Dec 15, 2020

I found one more related issue dependent intel arch.

XVim2 project imported rd_route project https://github.com/rodionovd/rd_route for getting swift function (property/method) pointer that not supporting arm arch.
We must fix it or change the dependent source/project for it.

NOTE: yes, using function function_ptr_from_name from it is for invoke swift method.
It is same purpose of SourceEditorViewWrapper.s assemble code.
If we found any other solution for it, we can remove both of code.

Refs:
https://github.com/XVimProject/XVim2/blob/master/XVim2/Helper/rd_route.c

@iT-Boyer
Copy link

There is a workaround. You can run Xcode using rosetta. Xcode is an universal application.

  1. Close Xcode
  2. Go to Applications and right click Xcode.
  3. Click "Get info" menu item in Context menu.
  4. Tick "Open using rosetta"
  5. Run Xcode
    Please notes that please make sure you have installed Xvim2.

It's unfortunately that the performance of Xcode is worse using Rosetta, especially building a big project.

I do this five steps and run XCode ,see Edit->Xvim2 -> about:

-------- Debug Info -------
XVim2 revision : 540f9b8cdbbc2a440cfd91f551981e801fc08f17
OS Version : Version 11.1 (Build 20C69)
Xcode Version : 12.3

--- .xvimrc ---
N/A
--------------

but , xvim2 not work in code editer .

@webcpu
Copy link

webcpu commented Dec 17, 2020

There is a workaround. You can run Xcode using rosetta. Xcode is an universal application.

  1. Close Xcode
  2. Go to Applications and right click Xcode.
  3. Click "Get info" menu item in Context menu.
  4. Tick "Open using rosetta"
  5. Run Xcode
    Please notes that please make sure you have installed Xvim2.

It's unfortunately that the performance of Xcode is worse using Rosetta, especially building a big project.

I do this five steps and run XCode ,see Edit->Xvim2 -> about:

-------- Debug Info -------
XVim2 revision : 540f9b8cdbbc2a440cfd91f551981e801fc08f17
OS Version : Version 11.1 (Build 20C69)
Xcode Version : 12.3

--- .xvimrc ---
N/A
--------------

but , xvim2 not work in code editer .

I have tested it on Xcode 12.2, it works. Because Xcode 12.3 isn't usable on my Mac, I haven't tested it on Xcode 12.3.

@r-plus
Copy link
Member

r-plus commented Dec 18, 2020

Do you add Xcode 12.3 UUID?

@iT-Boyer
Copy link

YES,i set UUID by this command:

find ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins -name Info.plist -maxdepth 3 | xargs -I{} defaults write {} DVTPlugInCompatibilityUUIDs -array-add `defaults read /Applications/Xcode.app/Contents/Info DVTPlugInCompatibilityUUID`

Now , when the mouse is focused on the editor, Xcode cannot respond for a long time.

@smolck
Copy link
Contributor

smolck commented Dec 29, 2020

Hello! So, my understanding from reading through this issue is that in order for XVim to work natively on M1, this assembly code needs to be removed/changed to work on ARM somehow, and rd_route also needs to be swapped out for something else or removed. Is that correct?

If so, I have a few questions; for starters, what does that x86 assembly do exactly/why is it used? Could it be replaced by Objective-C or C code?

Also, a quick glance over rd_route's README seems to suggest that it isn't very safe to use; I presume it can be used safely, but regardless I guess it could/should be replaced for something else? Perhaps a refactor could render it unnecessary?

I'm happy to help with this where I can, even if that just means testing out a PR or PRs on my machine to verify it works on M1.

Also, I can confirm that running Xcode under Rosetta does allow XVim to work, but I suspect running Xcode under Rosetta is something many M1 users (myself included) would rather avoid, considering the advantages to running Xcode natively on the M1.

@jspavlick
Copy link

jspavlick commented Dec 29, 2020

@smolck I believe your assessment is correct.

I do not know what the x86 assembly is doing. I am by no means an assembly expert. However, @r-plus is seeming to indicate that the assembly code is doing the same thing as rd_route, or somehow calling it? That doesn't seem to be the case to me, but I am no expert.

XVim2 is only using function_ptr_from_name from rd_route. If you read around in rd_route.c you can kind of get an idea of what it's doing. If you read around in SourceEditorViewWrapper.swift and SourceEditorDataSourceWrapper.swiift you can kind of get an idea on how it's being used.

I predict that converting the x86 assembly to ARM will be easier than porting the functionality of function_ptr_to_name but I don't know. (Unless r-plus is correct [as is my understanding of his earlier comment] and they're doing the same thing?)

My M1 Mac is on the way, and when it gets here I'll be happy to play with function_ptr_to_name as well as help in any other way I can.

In the meanwhile, I have posted a $500 bug bounty on this for anyone who is more competent than I am.

@smolck
Copy link
Contributor

smolck commented Dec 29, 2020

XVim2 is only using function_ptr_from_name from rd_route. If you read around in rd_route.c you can kind of get an idea of what it's doing. If you read around in SourceEditorViewWrapper.swift and SourceEditorDataSourceWrapper.swiift you can kind of get an idea on how it's being used.

Just looking at that first file, this is where function_ptr_from_name is used:

private let fpSetCursorStyle = function_ptr_from_name("_$s12SourceEditor0aB4ViewC11cursorStyleAA0ab6CursorE0Ovs", nil)
private let fpGetCursorStyle = function_ptr_from_name("_$s12SourceEditor0aB4ViewC11cursorStyleAA0ab6CursorE0Ovg", nil)
private let fpGetDataSource = function_ptr_from_name("_$s12SourceEditor0aB4ViewC04dataA0AA0ab4DataA0Cvg", nil)
private let fpSetSelectedRangeWithModifiers = function_ptr_from_name("_$s12SourceEditor0aB4ViewC16setSelectedRange_9modifiersySnyAA0aB8PositionVG_AA0aB18SelectionModifiersVtF", nil)
private let fpAddSelectedRangeWithModifiers = function_ptr_from_name("_$s12SourceEditor0aB4ViewC16addSelectedRange_9modifiers15scrollPlacement12alwaysScrollySnyAA0aB8PositionVG_AA0aB18SelectionModifiersVAA0kI0OSgSbtF", nil)

Those seem to just be pointers to Objective-C functions, right? For example, fpSetCursorStyle appears to reference this Objective-C function (or a similar one somewhere else in the code). In that case couldn't either (a) some sort of interop be done between Swift & Objective-C to remove the need for function_ptr_from_name (asking because I'm not super familiar with Swift or Objective-C), or (b) SourceEditorViewWrapper.swift just be rewritten in Objective-C so no interop is necessary?

As for (b), I imagine that might be the easier way of doing this, unless there's a serious reason why SourceEditorViewWrapper was written in Swift instead of Objective-C, or unless that class/file has to be written in Swift for some reason.

Again, though, I'm not familiar with this codebase (and hardly know anything about Swift/Objective-C), so I might be wrong here. (And even if I'm not and those are valid solutions, I don't think I currently have the understanding/knowledge necessary to implement the fix.)

@r-plus
Copy link
Member

r-plus commented Dec 30, 2020

Sorry for confusion.

Both parts (assembly code and rd_route) are necessary for invoke Swift method implemented in Xcode.app by Apple.

  1. getting Swift function (method) pointer by function_ptr_from_name
  2. Then call that pointer with argument by XVim assembly code

NOTE: Usually, pure Swift function (not have objc interface and not public level access control) have not dynamic callable system out side of original module (in this case, Xcode).

@jspavlick
Copy link

jspavlick commented Dec 30, 2020

Yeah, after studying the code a little more, I think @r-plus is completely correct.

Let me explain what I think is going on @smolck. SourceEditorViewWrapper wraps a SourceEditorView which is from some Apple internal framework. It is a Swift subclass of NSView. It's mangled name is _TtC15IDESourceEditor19IDESourceEditorView. It has methods on it like SourceEditor.SourceEditorView.setSelectedRange(_: SourceEditor.SourceEditorRange, modifiers: SourceEditor.SourceEditorSelectionModifiers) -> ()

SourceEditorViewWrapper wants to invoke these methods. When everything was Objective-C, you could just do something like [object performSelector:NSSelectorFromString(@"_someCrazyPrivateMethod")]; but in Swift land (unless the method is annotated with @objc) you cannot do this. (Note: even if SourceEditorViewWrapper was written in Objective-C, it still has this problem)

The workaround (which seems to be quite brilliant) is to get a function pointer that points to the function/method in question (I guess it's sitting in a v-table somewhere?) and then "manually" invoke the function as a method, by remembering to pass self as an argument. This manual invocation is what the x86 assembly code does I THINK.

@jspavlick
Copy link

@smolck could you please save this file as main.c and then run gcc main.c && ./a.out on your M1 mac and tell us what happens? https://pastebin.com/vKc8RG2K I stripped everything out of rd_route.c except function_ptr_from_name let's see if it works without any modification. It works on my Intel machine, for whatever little it's worth. 😅

@qiudaomao
Copy link
Contributor

@jspavlick
You are right, the magic SourceEditorViewWrapper.s does is to implement the swift function call ABI.

  1. Save registers
  2. Place all arguments in the right registers or stack
  3. call the function by symbol address
  4. restore the saved registers
  5. return

Need rewrite the whole procedure by ARM, de-compile some swift arm binaries should helping known how swift call a symbol in ARM.

@jspavlick
Copy link

@jspavlick

You are right, the magic SourceEditorViewWrapper.s does is to implement the swift function call ABI.

  1. Save registers

  2. Place all arguments in the right registers or stack

  3. call the function by symbol address

  4. restore the saved registers

  5. return

Need rewrite the whole procedure by ARM, de-compile some swift arm binaries should helping known how swift call a symbol in ARM.

And I think that's totally doable. But what do you think the chances are we get function_ptr_from_name also working on ARM?

@r-plus
Copy link
Member

r-plus commented Dec 30, 2020

@jspavlick yes, completely correct.

I’m thinking fishhook https://github.com/facebook/fishhook implementation is maybe helpful for getting function pointer on ARM. (looks like not have function like rd_route, so need work to fit for XVim)

@smolck
Copy link
Contributor

smolck commented Jan 12, 2021

but we'll have to find the equivalent knowledge for arm64.

That's the problem I'm having right now; for some reason there appears to be very little documentation on x64 assembly vs arm assembly, and it's quite frustrating.

However, I did find this write up which seems pretty useful: https://developer.apple.com/documentation/xcode/writing_armv6_code_for_ios

At the bottom of that there's a section regarding the prolog/epilog of a function, and some code as an example. My understanding from looking over the code there/reading a bit (I think I'll properly read through the whole thing later) is that the equivalent to leaq -240(%rsp), %rsp would be sub sp, sp, #240, but I'm not sure if that's correct. But perhaps specifically this code from that document might be useful:

push   {r4-r7, lr}     // Save Lr, R7, R4-R6.
mov    r6, r11         // Move high registers to low registers, so
mov    r5, r10         //  they can be saved. (Skip this part if
mov    r4, r8          //  the routine doesn’t use R8, R10, or R11.)
push   {r4-r6)         // Save R8, R10, R11 (now in R4-R6).
add    r7, sp, #24     // Adjust R7 to point to saved R7.
sub    sp, #36         // Allocate space for local storage.

If nothing else, it seems like a useful example of arm assembly.

@r-plus
Copy link
Member

r-plus commented Jan 13, 2021

I've been learning x64 assembly for the last few days before learning arm64 assembly.
Now I totally understood current assembly code what doing.

made this pull request for adding many comment and refactoring. #352

@r-plus
Copy link
Member

r-plus commented Jan 14, 2021

Hey guys!
I'm glad to announce start point to support arm64 architecture!

This is the branch to building universal binary. (Thank you @JugglerShu for commit permission)
It works basically operation in my test.
https://github.com/XVimProject/XVim2/tree/feature/support_arm

Let me know to this issue if you have the problem in arm, but not problem in intel.

known issues for arm

  • Xcode will crash when type Ctrl+v to enter Visual Block mode then type j key. I'm not sure how to resolve this. This crash is only happen on Debug build of XVim. Crash free on Release build :)

@jspavlick
Copy link

OMG!

@r-plus
Copy link
Member

r-plus commented Jan 15, 2021

ah, first known issue I wrote is only for Debug build.
uum, that's curious... but okey, mark as resolved.

@r-plus
Copy link
Member

r-plus commented Jan 15, 2021

Wow, I found test case for XVim inside edit menu.

This is result on ARM.
スクリーンショット 2021-01-15 21 43 38

and intel (Rosetta) result
intel_rosetta

Same result.
Hmm, is it release able quality...?

@jspavlick
Copy link

Are these issues present on Intel? I can't seem to find how to run these tests in Edit.

@r-plus
Copy link
Member

r-plus commented Jan 15, 2021

not yet checked about it.

tests are here.
Edit menu (in menu bar) -> XVim -> Test categories -> All

@jspavlick
Copy link

image

Am I crazy? I'm on master b723d4e

@r-plus
Copy link
Member

r-plus commented Jan 15, 2021

Oh, its menu will show only in debug mode. debug mode will add file logging AFAIK.
please did this.

echo "set debug" >> ~/.xvimrc

https://github.com/XVimProject/XVim2/blob/master/Documents/Contributing.md#debug-with-log

@jspavlick
Copy link

Got it!

Oh wow, Intel performs terribly! Can someone else with an Intel machine confirm this? This seems insane?

image

I ran it a second time and got this:
image

@r-plus
Copy link
Member

r-plus commented Jan 15, 2021

In my intel mac (MBP Late 2016), same three failure result I previously pasted.

@jspavlick
Copy link

Why does mine fail so badly? Maybe we can ignore it?

@smolck
Copy link
Contributor

smolck commented Jan 15, 2021

@jspavlick Is there anything other than set debug in you .xvimrc?

For me, I ran the tests on the latest from the feature/support_arm branch, and this was the result:
Screen Shot 2021-01-15 at 11 15 02 AM

Running it under Rosetta appeared to give the same thing.

Just from a quick test moving around the editor, it works well! Great work @r-plus!

@r-plus
Copy link
Member

r-plus commented Jan 16, 2021

Test result will be changed by Xcode preference.

dw failed two cases I pasted are passed when I disable the Xcode preference Including white-space only lines (Xcode default is off)
スクリーンショット 2021-01-16 13 34 23

After disabled it, only one failing case, same as @smolck's.
スクリーンショット 2021-01-16 13 30 07

@r-plus
Copy link
Member

r-plus commented Jan 16, 2021

looks like last failing test case O<ESC> is known broken test case commented as FIXME: expected text
https://github.com/XVimProject/XVim2/blob/master/XVim2/UnitTest/XVimTester%2BIssues.m#L87

initial text is "" empty string, then type O<ESC>, expected <CR>.
Where came from aaa bbb ccc string...?

Actually, Shift+o<ESC> is correctly works well :)

@r-plus
Copy link
Member

r-plus commented Jan 16, 2021

fixed blank text initializing for unit test and test case expected result for fitting Xcode 12. a8a3e88

finally, all passed.
スクリーンショット 2021-01-16 14 26 18

@jspavlick
Copy link

@jspavlick Is there anything other than set debug in you .xvimrc?

For me, I ran the tests on the latest from the feature/support_arm branch, and this was the result:
Screen Shot 2021-01-15 at 11 15 02 AM

Running it under Rosetta appeared to give the same thing.

Just from a quick test moving around the editor, it works well! Great work @r-plus!

after emptying my .xvimrc and switching to feature/support_arm a8a3e88 I still get this. Maybe we should just ignore my sad machine and test results 😅

image

@r-plus
Copy link
Member

r-plus commented Jan 16, 2021

@jspavlick This unit test expected Xcode default preference.
Looking your results, Expected and Actual differences are space width.
Are you changing indent preference?

@jspavlick
Copy link

Good thinking, @r-plus ! After changing my indentation from 2 to 4 in Xcode, everything passes!

image

@jspavlick
Copy link

I got my M1 Mac Mini (finally) and have set it up. Wow, this thing is amazing. Product > Archive is 3.7x faster than my Mid 2014 MBP, and I simply cannot get this thing to make fan noise. It's dead silent.

I got XVim2 installed and working. All 463 tests pass. And Xvim seems to work perfectly from what I can tell. Very good job @r-plus !

I did get one crash while running the tests, but I can't replicate it. Probably not a big deal. I am also experiencing this issue: #340

image

@jhirsh
Copy link

jhirsh commented Jan 22, 2021

feature/support-arm also passes on my M1 MBA.

@r-plus, thank you for tackling this! 🦾

@jspavlick
Copy link

@r-plus when are we merging this into master? Go claim your bounty!

@r-plus
Copy link
Member

r-plus commented Jan 23, 2021

@jspavlick I'm wondering if it's okay to self-merging pull request. (I’m new face of committer for this repo)

@pebble8888
Copy link
Member Author

@r-plus
I think you can merge your PR and close this issue.

@r-plus
Copy link
Member

r-plus commented Jan 23, 2021

okey, thanks! I'll merge it.

@r-plus
Copy link
Member

r-plus commented Jan 23, 2021

I just merge it to develop and master branches.
Close this issue, thanks to all supported great vimmers.

@r-plus r-plus closed this as completed Jan 23, 2021
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