aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lux/compiler/case.clj55
-rw-r--r--src/lux/compiler/host.clj29
2 files changed, 47 insertions, 37 deletions
diff --git a/src/lux/compiler/case.clj b/src/lux/compiler/case.clj
index 9d885942f..9d709bae2 100644
--- a/src/lux/compiler/case.clj
+++ b/src/lux/compiler/case.clj
@@ -40,6 +40,11 @@
(.visitInsn Opcodes/POP2)
(pop-alt-stack (- stack-depth 2)))))
+(defn ^:private stack-peek [^MethodVisitor writer]
+ (doto writer
+ (.visitInsn Opcodes/DUP)
+ (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")))
+
(defn ^:private compile-pattern* [^MethodVisitor writer bodies stack-depth $else pm]
"(-> MethodVisitor Case-Pattern (List Label) Int Label MethodVisitor)"
(|case pm
@@ -59,63 +64,59 @@
(&o/$BindPM _var-id)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
+ stack-peek
(.visitVarInsn Opcodes/ASTORE _var-id)
(.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_pop" "([Ljava/lang/Object;)[Ljava/lang/Object;"))
(&o/$BoolPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
- (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Boolean")
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Boolean" "booleanValue" "()Z")
+ stack-peek
+ &&/unwrap-boolean
(.visitLdcInsn _value)
(.visitJumpInsn Opcodes/IF_ICMPNE $else))
(&o/$NatPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
- (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Long")
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Long" "longValue" "()J")
+ stack-peek
+ &&/unwrap-long
(.visitLdcInsn (long _value))
(.visitInsn Opcodes/LCMP)
(.visitJumpInsn Opcodes/IFNE $else))
(&o/$IntPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
- (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Long")
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Long" "longValue" "()J")
+ stack-peek
+ &&/unwrap-long
+ (.visitLdcInsn (long _value))
+ (.visitInsn Opcodes/LCMP)
+ (.visitJumpInsn Opcodes/IFNE $else))
+
+ (&o/$FracPM _value)
+ (doto writer
+ stack-peek
+ &&/unwrap-long
(.visitLdcInsn (long _value))
(.visitInsn Opcodes/LCMP)
(.visitJumpInsn Opcodes/IFNE $else))
(&o/$RealPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
- (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Double")
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Double" "doubleValue" "()D")
+ stack-peek
+ &&/unwrap-double
(.visitLdcInsn (double _value))
(.visitInsn Opcodes/DCMPL)
(.visitJumpInsn Opcodes/IFNE $else))
(&o/$CharPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
- (.visitTypeInsn Opcodes/CHECKCAST "java/lang/Character")
- (.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Character" "charValue" "()C")
+ stack-peek
+ &&/unwrap-char
(.visitLdcInsn _value)
(.visitJumpInsn Opcodes/IF_ICMPNE $else))
(&o/$TextPM _value)
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
+ stack-peek
(.visitLdcInsn _value)
(.visitMethodInsn Opcodes/INVOKEVIRTUAL "java/lang/Object" "equals" "(Ljava/lang/Object;)Z")
(.visitJumpInsn Opcodes/IFEQ $else))
@@ -128,8 +129,7 @@
(&/$Right _idx)
(&/T [_idx true]))]
(doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
+ stack-peek
(.visitTypeInsn Opcodes/CHECKCAST "[Ljava/lang/Object;")
(.visitLdcInsn (int _idx))
(.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" (if is-tail? "product_getRight" "product_getLeft") "([Ljava/lang/Object;I)Ljava/lang/Object;")
@@ -146,8 +146,7 @@
(&/$Right _idx)
(&/T [_idx true]))
_ (doto writer
- (.visitInsn Opcodes/DUP)
- (.visitMethodInsn Opcodes/INVOKESTATIC "lux/LuxRT" "pm_stack_peek" "([Ljava/lang/Object;)Ljava/lang/Object;")
+ stack-peek
(.visitTypeInsn Opcodes/CHECKCAST "[Ljava/lang/Object;")
(.visitLdcInsn (int _idx)))
_ (if is-last
diff --git a/src/lux/compiler/host.clj b/src/lux/compiler/host.clj
index 3b2a53929..6c1646933 100644
--- a/src/lux/compiler/host.clj
+++ b/src/lux/compiler/host.clj
@@ -687,11 +687,22 @@
(.visitInsn Opcodes/ARETURN)
(.visitMaxs 0 0)
(.visitEnd)))
- _ (let [$is-null (new Label)]
+ _ (let [;; $is-null (new Label)
+ ]
+ ;; I commented out some parts because a null-check was
+ ;; done to ensure variants were never created with null
+ ;; values (this would interfere later with
+ ;; pattern-matching).
+ ;; Since Lux itself doesn't have null values as part of
+ ;; the language, the burden of ensuring non-nulls was
+ ;; shifted to library code dealing with host-interop, to
+ ;; ensure variant-making was as fast as possible.
+ ;; The null-checking code was left as comments in case I
+ ;; ever change my mind.
(doto (.visitMethod =class (+ Opcodes/ACC_PUBLIC Opcodes/ACC_STATIC) "sum_make" "(ILjava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;" nil nil)
(.visitCode)
- (.visitVarInsn Opcodes/ALOAD 2)
- (.visitJumpInsn Opcodes/IFNULL $is-null)
+ ;; (.visitVarInsn Opcodes/ALOAD 2)
+ ;; (.visitJumpInsn Opcodes/IFNULL $is-null)
(.visitLdcInsn (int 3))
(.visitTypeInsn Opcodes/ANEWARRAY "java/lang/Object")
(.visitInsn Opcodes/DUP)
@@ -708,12 +719,12 @@
(.visitVarInsn Opcodes/ALOAD 2)
(.visitInsn Opcodes/AASTORE)
(.visitInsn Opcodes/ARETURN)
- (.visitLabel $is-null)
- (.visitTypeInsn Opcodes/NEW "java/lang/IllegalStateException")
- (.visitInsn Opcodes/DUP)
- (.visitLdcInsn "Can't create variant for null pointer")
- (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/IllegalStateException" "<init>" "(Ljava/lang/String;)V")
- (.visitInsn Opcodes/ATHROW)
+ ;; (.visitLabel $is-null)
+ ;; (.visitTypeInsn Opcodes/NEW "java/lang/IllegalStateException")
+ ;; (.visitInsn Opcodes/DUP)
+ ;; (.visitLdcInsn "Can't create variant for null pointer")
+ ;; (.visitMethodInsn Opcodes/INVOKESPECIAL "java/lang/IllegalStateException" "<init>" "(Ljava/lang/String;)V")
+ ;; (.visitInsn Opcodes/ATHROW)
(.visitMaxs 0 0)
(.visitEnd)))]
nil))