diff options
Diffstat (limited to '')
-rw-r--r-- | src/lux/compiler/case.clj | 55 | ||||
-rw-r--r-- | src/lux/compiler/host.clj | 29 |
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)) |