diff --git a/Makefile b/Makefile index 923ae72..da83501 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,8 @@ CC ?= gcc ARCH = -m32 CFLAGS += -Wall -Werror -Wfatal-errors -Wno-error=unused-variable -fstack-protector -std=c2x -g CFLAGS += -DDEBUG -#CFLAGS += -DDEBUG_PRINT +CFLAGS += -DDEBUG_PRINT +LDFLAGS = -lm OPT ?= -O0 DEPFLAGS = -MMD -MP @@ -15,10 +16,10 @@ DEPFLAGS = -MMD -MP $(CC) $(ARCH) $(CFLAGS) $(OPT) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ print_class: $(OBJ) $(PRINT_CLASS_OBJ) - $(CC) $(ARCH) $^ -o $@ + $(CC) $(ARCH) $(LDFLAGS) $^ -o $@ main: $(OBJ) $(MAIN_HOSTED_OBJ) - $(CC) $(ARCH) $^ -o $@ + $(CC) $(ARCH) $(LDFLAGS) $^ -o $@ clean: rm -f main print_class c/*.o c/*.d *.elf *.bin diff --git a/c/frame.c b/c/frame.c index 019b980..9842b67 100644 --- a/c/frame.c +++ b/c/frame.c @@ -214,23 +214,25 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str struct constant * method_name_constant = &class_entry->class_file->constant_pool[method_info->name_index - 1]; print_constant(method_name_constant); - int java_io_printstream_length = 19; - bool java_io_printstream = - class_name_constant->utf8.length == java_io_printstream_length && - hash_table_key_equal(class_name_constant->utf8.bytes, (const uint8_t *)"java/io/PrintStream", class_name_constant->utf8.length); - if (java_io_printstream) { - int write_length = 5; - bool write = - method_name_constant->utf8.length == write_length && - hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"write", method_name_constant->utf8.length); - if (write) { - if (nargs == 1) { - assert(return_type == 'V'); - native_java_io_printstream_write_1(args); + + int java_lang_math_length = 14; + bool java_lang_math = + class_name_constant->utf8.length == java_lang_math_length && + hash_table_key_equal(class_name_constant->utf8.bytes, (const uint8_t *)"java/lang/Math", class_name_constant->utf8.length); + if (java_lang_math) { + if (method_name_constant->utf8.length == 3) { + if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"sin", 3)) { + assert(nargs == 1); + assert(return_type == 'F'); + uint32_t value = native_java_lang_math_sin_1(args); + operand_stack_push_u32(vm->current_frame, value); return; - } else if (nargs == 2) { - assert(return_type == 'V'); - native_java_io_printstream_write_2(args); + } + if (hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"cos", 3)) { + assert(nargs == 1); + assert(return_type == 'F'); + uint32_t value = native_java_lang_math_cos_1(args); + operand_stack_push_u32(vm->current_frame, value); return; } } @@ -269,6 +271,28 @@ void vm_native_method_call(struct vm * vm, struct class_entry * class_entry, str } } + int java_io_printstream_length = 19; + bool java_io_printstream = + class_name_constant->utf8.length == java_io_printstream_length && + hash_table_key_equal(class_name_constant->utf8.bytes, (const uint8_t *)"java/io/PrintStream", class_name_constant->utf8.length); + if (java_io_printstream) { + int write_length = 5; + bool write = + method_name_constant->utf8.length == write_length && + hash_table_key_equal(method_name_constant->utf8.bytes, (const uint8_t *)"write", method_name_constant->utf8.length); + if (write) { + if (nargs == 1) { + assert(return_type == 'V'); + native_java_io_printstream_write_1(args); + return; + } else if (nargs == 2) { + assert(return_type == 'V'); + native_java_io_printstream_write_2(args); + return; + } + } + } + assert(false); } diff --git a/c/native.c b/c/native.c index d73cb2a..bf2c14f 100644 --- a/c/native.c +++ b/c/native.c @@ -62,3 +62,17 @@ uint32_t native_java_misc_memory_getU1_1(uint32_t * args) uint8_t value = *address; return value; } + +uint32_t native_java_lang_math_sin_1(uint32_t * args) +{ + float arg = ((float *)args)[0]; + float value = __builtin_sinf(arg); + return *((uint32_t *)&value); +} + +uint32_t native_java_lang_math_cos_1(uint32_t * args) +{ + float arg = ((float *)args)[0]; + float value = __builtin_cosf(arg); + return *((uint32_t *)&value); +} diff --git a/c/native.h b/c/native.h index 485f668..4d7a579 100644 --- a/c/native.h +++ b/c/native.h @@ -11,3 +11,5 @@ void native_java_misc_memory_putU1_2(uint32_t * args); uint32_t native_java_misc_memory_getU4_1(uint32_t * args); uint32_t native_java_misc_memory_getU2_1(uint32_t * args); uint32_t native_java_misc_memory_getU1_1(uint32_t * args); +uint32_t native_java_lang_math_sin_1(uint32_t * args); +uint32_t native_java_lang_math_cos_1(uint32_t * args); diff --git a/java/lang/Math.java b/java/lang/Math.java new file mode 100644 index 0000000..346652e --- /dev/null +++ b/java/lang/Math.java @@ -0,0 +1,20 @@ +package java.lang; + +public final class Math { + + private Math() {} + + public static final float E = 2.718281828459045f; + + public static final float PI = 3.141592653589793f; + + public static final float TAU = 2.0f * PI; + + public static final float DEGREES_TO_RADIANS = 0.017453292519943295f; + + public static final float RADIANS_TO_DEGREES = 57.29577951308232f; + + public static native float sin(float a); + + public static native float cos(float a); +} diff --git a/p/SinCos.java b/p/SinCos.java new file mode 100644 index 0000000..f3ba5a3 --- /dev/null +++ b/p/SinCos.java @@ -0,0 +1,13 @@ +package p; + +import java.lang.Math; + +class SinCos { + static float test() { + return Math.cos(1.4f); + } + + public static void main() { + test(); + } +}