Skip to content

Commit 634337b

Browse files
committed
fix call java.lang.Object methods for primitive
1 parent d9841ef commit 634337b

2 files changed

Lines changed: 45 additions & 9 deletions

File tree

src/org/mirah/jvm/compiler/call_compiler.mirah

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import mirah.objectweb.asm.Opcodes
3030
import mirah.objectweb.asm.Type
3131
import mirah.objectweb.asm.commons.GeneratorAdapter
3232
import mirah.objectweb.asm.commons.Method
33+
import static org.mirah.jvm.types.JVMTypeUtils.*
3334

3435
class CallCompiler < BaseCompiler implements MemberVisitor
3536
def self.initialize:void
@@ -274,10 +275,15 @@ class CallCompiler < BaseCompiler implements MemberVisitor
274275
def visitMethodCall(method:JVMMethod, expression:boolean)
275276
isVoid = method.returnType.getAsmType.getDescriptor.equals('V')
276277
compile(@target)
278+
targetType = getInferredType(@target)
279+
if isPrimitive(targetType)
280+
# java.lang.Object method called on primitive - call on boxed instance
281+
@method.box(targetType.getAsmType)
282+
end
277283
returnType = method.returnType
278284
if expression && isVoid
279285
@method.dup
280-
returnType = getInferredType(@target)
286+
returnType = targetType
281287
end
282288
convertArgs(method.argumentTypes)
283289
recordPosition
@@ -384,6 +390,10 @@ class CallCompiler < BaseCompiler implements MemberVisitor
384390

385391
def visitInstanceof(method, expression)
386392
compile(@target)
393+
type = getInferredType(@target)
394+
if isPrimitive(type)
395+
raise VerifyError, "kind_of? operation not defined for #{@target} with type #{getInferredType(@target)} #{getInferredType(@target).getClass}"
396+
end
387397
if expression
388398
@method.instanceOf(getInferredType(@args[0]).getAsmType)
389399
else
@@ -395,14 +405,21 @@ class CallCompiler < BaseCompiler implements MemberVisitor
395405
compile(@target)
396406
if expression
397407
recordPosition
398-
nonNull = @method.newLabel
399-
done = @method.newLabel
400-
@method.ifNonNull(nonNull)
401-
@method.push(1)
402-
@method.goTo(done)
403-
@method.mark(nonNull)
404-
@method.push(0)
405-
@method.mark(done)
408+
type = getInferredType(@target)
409+
if isPrimitive(type)
410+
# always not null
411+
@method.pop(type)
412+
@method.push(0)
413+
else
414+
nonNull = @method.newLabel
415+
done = @method.newLabel
416+
@method.ifNonNull(nonNull)
417+
@method.push(1)
418+
@method.goTo(done)
419+
@method.mark(nonNull)
420+
@method.push(0)
421+
@method.mark(done)
422+
end
406423
else
407424
@method.pop
408425
end

test/jvm/extensions/numeric_operators_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,23 @@ def test_unary_minus
113113
assert_run_output("-1.0\njava.lang.#{type}\n", cls)
114114
end
115115
end
116+
117+
def test_numeric_object_methods
118+
cls, = compile("puts 1.hashCode === Integer.new(1).hashCode
119+
puts 1.equals(Integer.new(1))
120+
puts 1.equals(nil)
121+
puts 1.equals('1')
122+
puts false.equals(false)
123+
puts 1.nil?
124+
125+
")
126+
assert_run_output("true\ntrue\nfalse\nfalse\ntrue\nfalse\n", cls)
127+
128+
begin
129+
compile("1.kind_of? Integer")
130+
fail "kind_of? for primitve not supported"
131+
rescue
132+
# ok
133+
end
134+
end
116135
end

0 commit comments

Comments
 (0)