Skip to content

Commit

Permalink
Merge pull request #68 from anatawa12/crashes-when-click-search-light
Browse files Browse the repository at this point in the history
crash when click search light
  • Loading branch information
anatawa12 authored May 22, 2020
2 parents b9a89a3 + 96f6bc1 commit 3d555d7
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/main/java/com/anatawa12/fixRtm/asm/RhinoTransformer.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.anatawa12.fixRtm.asm

import com.anatawa12.fixRtm.scripting.PrimitiveJavaHelper
import com.anatawa12.fixRtm.scripting.RhinoHooks
import net.minecraft.launchwrapper.IClassTransformer
import org.objectweb.asm.*
Expand All @@ -17,6 +18,11 @@ class RhinoTransformer : IClassTransformer {
val writer = ClassWriter(0)
reader.accept(NativeJavaObjectVisitor(writer), 0)
return writer.toByteArray()
} else if (name == PrimitiveJavaHelper.NativeString_name) {
val reader = ClassReader(basicClass!!)
val writer = ClassWriter(0)
reader.accept(NativeStringVisitor(writer), 0)
return writer.toByteArray()
}
return basicClass
}
Expand Down Expand Up @@ -108,6 +114,34 @@ class RhinoTransformer : IClassTransformer {
}
}

class NativeStringVisitor(visitor: ClassVisitor): ClassVisitor(ASM5, visitor) {
override fun visitEnd() {
visitMethod(ACC_PUBLIC, PrimitiveJavaHelper.get_name, PrimitiveJavaHelper.get_desc,
null, null).apply {
visitCode()
visitVarInsn(ALOAD, 0) // this
visitVarInsn(ALOAD, 1) // name
visitVarInsn(ALOAD, 2) // start
visitMethodInsn(INVOKESPECIAL, IdScriptableObject_internal, PrimitiveJavaHelper.get_name, PrimitiveJavaHelper.get_desc, false)
visitInsn(DUP)
visitFieldInsn(GETSTATIC, Scriptable_internal, Scriptable_NOT_FOUND_name, Scriptable_NOT_FOUND_desc)
val ifEq = Label()
visitJumpInsn(IF_ACMPEQ, ifEq)
visitInsn(ARETURN)
visitLabel(ifEq)
visitFrame(F_SAME1, 0, null, 1, arrayOf("java/lang/Object"))
visitInsn(POP)
visitVarInsn(ALOAD, 1) // name
visitVarInsn(ALOAD, 2) // start
visitMethodInsn(INVOKESTATIC, PrimitiveJavaHelper.internalClassName, PrimitiveJavaHelper.NativeString_get_hook_name, PrimitiveJavaHelper.NativeString_get_hook_desc, false)
visitInsn(ARETURN)
visitMaxs(3, 3)
visitEnd()
}
super.visitEnd()
}
}

class InsertCodeAtFirstVisitor(visitor: MethodVisitor, private val function: MethodVisitor.() -> Unit)
: MethodVisitor(ASM5, visitor) {
private var visited = false
Expand All @@ -127,5 +161,9 @@ class RhinoTransformer : IClassTransformer {
const val NativeJavaObject_name = "org.mozilla.javascript.NativeJavaObject"
const val NativeJavaObject_internal = "org/mozilla/javascript/NativeJavaObject"
const val CoerceTypeImplFailed_internal = "com/anatawa12/fixRtm/scripting/CoerceTypeImplFailed"
const val IdScriptableObject_internal = "org/mozilla/javascript/IdScriptableObject"
const val Scriptable_internal = "org/mozilla/javascript/Scriptable"
const val Scriptable_NOT_FOUND_name = "NOT_FOUND"
const val Scriptable_NOT_FOUND_desc = "L${"java/lang/Object"};"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.anatawa12.fixRtm.scripting

import org.mozilla.javascript.*

@Suppress("FunctionName")
object PrimitiveJavaHelper {
const val internalClassName = "com/anatawa12/fixRtm/scripting/PrimitiveJavaHelper"

const val NativeString_name = "org.mozilla.javascript.NativeString"
const val NativeString_internal = "org/mozilla/javascript/NativeString"
const val get_name = "get"
const val get_desc = "(Lj${"ava/lang/String"};L${"org/mozilla/javascript/Scriptable"};)L${"java/lang/Object"};"
const val NativeString_get_hook_name = "NativeString_get"
const val NativeString_get_hook_desc = "(L${"java/lang/String"};L${"org/mozilla/javascript/Scriptable"};)L${"java/lang/Object"};"
const val NativeString_string_name = "string"
const val NativeString_string_desc = "L${"java/lang/CharSequence"};"

@JvmStatic
fun NativeString_get(name: String?, start: Scriptable?): Any? {
if (name in StringMethod_names) return Scriptable.NOT_FOUND
return wrapFunctionForString(stringObject.get(name, start))
}

private val stringObject = NativeJavaObject(null, "", null)

private fun wrapFunctionForString(scriptable: Any?): Any? {
if (scriptable is NativeJavaMethod)
return FixRTMWrappedFunction(scriptable, ::getStringInstance)
else
return scriptable
}

@JvmStatic
fun getStringInstance(scriptable: Scriptable) = FixRTMRhinoAccessor.getStringOfNativeString(scriptable)

val StringMethod_names = setOf(
"charAt", "charCodeAt", "codePointAt", "concat", "includes", "endsWith", "indexOf", "lastIndexOf",
"localeCompare", "match", "normalize", "padEnd", "padStart", "quote", "repeat", "replace", "search",
"slice", "split", "startsWith", "substr", "substring", "toLocaleLowerCase", "toLocaleUpperCase",
"toLowerCase", "toSource", "toString", "toUpperCase", "trim", "trimStart", "trimLeft", "trimEnd",
"trimRight", "valueOf", "anchor", "big", "blink", "bold", "fixed", "fontcolor", "fontsize", "italics",
"link", "small", "strike", "sub", "sup"
)
}
25 changes: 25 additions & 0 deletions src/main/java/com/anatawa12/fixRtm/scripting/inRhinoPackage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@file:Suppress("PackageDirectoryMismatch")

package org.mozilla.javascript

class FixRTMWrappedFunction(private val javaFunction: NativeJavaMethod, private val getInstance: (Scriptable) -> Any?) : BaseFunction() {
override fun getFunctionName(): String = javaFunction.functionName
override fun decompile(indent: Int, flags: Int): String = javaFunction.decompile(indent, flags)
override fun toString(): String = javaFunction.toString()

override fun call(cx: Context, scope: Scriptable, thisObj: Scriptable?, args: Array<out Any>?): Any {
return javaFunction.call(cx, scope, thisObj?.let { wrap(cx, scope, thisObj) }, args)
}

private fun wrap(cx: Context, scope: Scriptable, thisObj: Scriptable?): Scriptable? {
if (thisObj == null) return null
val topLevel = ScriptableObject.getTopLevelScope(scope)
return cx.wrapFactory.wrapNewObject(cx, topLevel, getInstance(thisObj))
}
}

object FixRTMRhinoAccessor {
fun getStringOfNativeString(scriptable: Scriptable): String?
= (scriptable as? NativeString)?.toCharSequence()?.toString()

}

0 comments on commit 3d555d7

Please sign in to comment.