Permalink
Browse files

Initial import

  • Loading branch information...
0 parents commit 52ee7dc82dc954f084be54662b32024d408d0971 @landonf committed Apr 14, 2011
Showing with 5,363 additions and 0 deletions.
  1. +23 −0 LICENSE
  2. +204 −0 Other Sources/gentramp.sh
  3. +26 −0 README.md
  4. +2 −0 Resources/English.lproj/InfoPlist.strings
  5. +28 −0 Resources/Info.plist
  6. +451 −0 Resources/MainWindow.xib
  7. +22 −0 Resources/PLBlockIMP-iOS-Tests-Info.plist
  8. +22 −0 Resources/PLBlockIMP-iOSimulator-Tests-Info.plist
  9. +22 −0 Resources/Tests-MacOSX-Info.plist
  10. +66 −0 Source/ARM/blockimp_arm.tramp
  11. +61 −0 Source/ARM/blockimp_arm_stret.tramp
  12. +28 −0 Source/PLBlockIMP.h
  13. +117 −0 Source/blockimp.c
  14. +31 −0 Source/blockimp.h
  15. +135 −0 Source/blockimp_private.h
  16. +148 −0 Source/blockimp_tests.m
  17. +202 −0 Source/trampoline_table.c
  18. +92 −0 Source/trampoline_table.h
  19. +67 −0 Source/x86_32/blockimp_x86_32.tramp
  20. +67 −0 Source/x86_32/blockimp_x86_32_stret.tramp
  21. +62 −0 Source/x86_64/blockimp_x86_64.tramp
  22. +62 −0 Source/x86_64/blockimp_x86_64_stret.tramp
  23. +13 −0 Tools/README.txt
  24. +202 −0 Tools/google-toolbox-for-mac-1-5-1/COPYING
  25. +166 −0 Tools/google-toolbox-for-mac-1-5-1/GTMDefines.h
  26. +140 −0 Tools/google-toolbox-for-mac-1-5-1/ReleaseNotes.txt
  27. +31 −0 Tools/google-toolbox-for-mac-1-5-1/UnitTesting/GTMIPhoneUnitTestDelegate.h
  28. +160 −0 Tools/google-toolbox-for-mac-1-5-1/UnitTesting/GTMIPhoneUnitTestDelegate.m
  29. +33 −0 Tools/google-toolbox-for-mac-1-5-1/UnitTesting/GTMIPhoneUnitTestMain.m
  30. +1,004 −0 Tools/google-toolbox-for-mac-1-5-1/UnitTesting/GTMSenTestCase.h
  31. +211 −0 Tools/google-toolbox-for-mac-1-5-1/UnitTesting/GTMSenTestCase.m
  32. +1,465 −0 blockimp.xcodeproj/project.pbxproj
23 LICENSE
@@ -0,0 +1,23 @@
+Author: Landon Fuller <landonf@plausible.coop>
+
+Copyright 2010-2011 Plausible Labs Cooperative, Inc.
+All rights reserved.
+
+Permission is hereby granted, free of charge,
+to any person obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
@@ -0,0 +1,204 @@
+#!/bin/sh
+
+# -----------------------------------------------------------------------
+# gentramp.sh - Copyright (c) 2010-2011, Plausible Labs Cooperative, Inc.
+#
+# Trampoline Page Generator
+# Author: Landon Fuller <landonf@plausible.coop>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# ``Software''), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+# -----------------------------------------------------------------------
+
+PROGNAME=$0
+
+OUTPUT_DIR="$1"
+SRC_C_OUTPUT="${OUTPUT_DIR}/${INPUT_FILE_BASE}_config.c"
+SRC_OUTPUT="${OUTPUT_DIR}/${INPUT_FILE_BASE}.s"
+HEADER_OUTPUT="${OUTPUT_DIR}/${INPUT_FILE_BASE}.h"
+
+# Default implementation
+trampoline_prefix () {
+ return 0
+}
+
+# Import the trampoline definition
+. ${INPUT_FILE_PATH}
+
+check_required () {
+ local name=$1
+ eval "local var=\${$1}"
+
+ if [ -z "${var}" ]; then
+ echo "Required variable ${name} not defined."
+ exit 1
+ fi
+}
+
+check_required ARCH
+check_required PAGE_SIZE
+check_required PAGE_NAME
+
+# Write a header line
+header () {
+ echo "$1" >> "${HEADER_OUTPUT}"
+}
+
+# Write a C source line
+src () {
+ echo "$1" >> "${SRC_C_OUTPUT}"
+}
+
+# Flush the assembler output buffer to disk
+ASM_BUFFER=""
+asm_flush () {
+ echo "${ASM_BUFFER}" >> "${SRC_OUTPUT}"
+ asm_discard
+}
+
+# Write the assembler buffer to disk, but don't discard the contents
+asm_write () {
+ echo "${ASM_BUFFER}" >> "${SRC_OUTPUT}"
+}
+
+# Discard the current assembler output buffer
+asm_discard () {
+ ASM_BUFFER=''
+ return 0;
+}
+
+# Append data to the assembler output buffer
+asm () {
+ local line=""
+ while read -r line; do
+ ASM_BUFFER+=$line
+ ASM_BUFFER+="\n"
+ done
+}
+
+# Compute the assembled size of the current assembler buffer
+compute_asm_size () {
+ # Create the temporary assembler file
+ local output=".globl _byte_count_start\n"
+ output+="_byte_count_start:\n"
+ output+="${ASM_BUFFER}"
+ output+=".globl _byte_count_end\n"
+ output+="_byte_count_end:\n"
+
+ local tempfile=`mktemp /tmp/as_bytecount.XXXXXXXX`
+ echo "${output}" | as -arch "${CURRENT_ARCH}" -o "${tempfile}" -
+ if [ $? != 0 ]; then
+ echo "Assembling the trampoline failed"
+ exit 1
+ fi
+
+ local byte_size=`nm -t d -P "${tempfile}" | grep ^_byte_count_end | awk '{print $3}'`
+ rm -f "${tempfile}"
+
+ echo $byte_size
+}
+
+
+# Write out the page header
+write_page_decl () {
+ # Calculate the required alignment
+ local align=`perl -l -e "print log(${PAGE_SIZE})/log(2)"`
+ asm << EOF
+ # GENERATED CODE - DO NOT EDIT"
+ # This file was generated by $PROGNAME on `date`
+
+ # Write out the trampoline table, aligned to the page boundary
+ .text
+ .align ${align}
+ .globl _${PAGE_NAME}
+ _${PAGE_NAME}:
+EOF
+}
+
+main () {
+ echo '' > "${SRC_OUTPUT}"
+ echo '' > "${SRC_C_OUTPUT}"
+ echo '' > "${HEADER_OUTPUT}"
+
+ # Write out the trampoline header file
+ header "extern void *${PAGE_NAME};"
+ header "extern struct pl_trampoline_table_config ${PAGE_NAME}_config;"
+
+ # Don't generate the sources for the incorrect arch
+ if [ "${ARCH}" != "${CURRENT_ARCH}" ]; then
+ return
+ fi
+
+ # Determine the trampoline prefix size
+ trampoline_prefix
+ local prefix_size=$(compute_asm_size)
+ asm_discard
+
+ # Compute the size of the remaining code page.
+ local page_avail=`expr $PAGE_SIZE - $prefix_size`
+
+ # Determine the trampoline size
+ trampoline
+ local tramp_size=$(compute_asm_size)
+ asm_discard
+ if [ "${tramp_size}" = 0 ]; then
+ echo "Error occured calculating trampoline size; received size of 0"
+ exit 1
+ fi
+
+ # Compute the number of of available trampolines.
+ local trampoline_count=`expr $page_avail / $tramp_size`
+ echo "Prefix size: ${prefix_size}"
+ echo "Trampoline size: ${tramp_size}"
+ echo "Trampolines per page: ${trampoline_count}"
+
+ # Write out the page declaration
+ write_page_decl
+ asm_flush
+
+ # Write out the prefix
+ trampoline_prefix
+ asm_flush
+
+ # Write out the trampolines
+ trampoline
+ local i=0
+ while [ $i -lt ${trampoline_count} ]; do
+ asm_write
+ local i=`expr $i + 1`
+ done
+ asm_discard
+
+ # Write out the table configuration
+ local config_src=`cat << EOF
+ #include "trampoline_table.h"
+
+ extern void *${PAGE_NAME};
+ pl_trampoline_table_config ${PAGE_NAME}_config = {
+ .trampoline_size = ${tramp_size},
+ .page_offset = ${prefix_size},
+ .trampoline_count = ${trampoline_count},
+ .template_page = &${PAGE_NAME}
+ };
+EOF`
+ src "${config_src}"
+}
+
+main
@@ -0,0 +1,26 @@
+PLBlockIMP
+-----------
+
+
+PLBlockIMP provides an open-source implementation of [imp_implementationWithBlock()](http://www.friday.com/bbum/2011/03/17/ios-4-3-imp_implementationwithblock/), using
+vm_remap()-based trampolines, as described in [Implementing imp_implementationWithBlock](http://landonf.bikemonkey.org/code/objc/imp_implementationWithBlock.20110413.html).
+
+PLBlockIMP will generate a lightweight, high-performance function pointer trampoline that may be used to register a block as an Objective-C method implementation. Mac OS X 10.6+ and
+iOS 4.0+ are supported.
+
+Additionally, PLBlockIMP contains a generic trampoline allocator and set of generator scripts that may be used to implement custom trampoline pages on Mac OS X and iOS.
+
+PLBlockIMP is released under the MIT license.
+
+Sample Use
+-----------
+
+Use a block to add a new method to NSObject (based on Mike Ash's MABlockClosure example):
+
+ int captured = 42;
+ id block = ^(id self, SEL _cmd) { NSLog(@"captured is %d", captured); };
+ block = [block copy];
+ class_addMethod([NSObject class], @selector(my_printCaptured), pl_imp_implementationWithBlock(block), "v@:");
+
+Additionally, pl_imp_getBlock() may be used to fetch the block associated with an IMP trampoline, and pl_imp_removeBlock() to discard a trampoline
+and its associated block reference.
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.yourcompany.${PRODUCT_NAME:rfc1034Identifier}</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>NSPrincipalClass</key>
+ <string></string>
+</dict>
+</plist>
Oops, something went wrong.

0 comments on commit 52ee7dc

Please sign in to comment.