Skip to content

Commit 612b822

Browse files
committed
fixup: improve wasm module
Signed-off-by: Simon Schrottner <simon.schrottner@dynatrace.com>
1 parent 6ac3a1f commit 612b822

3 files changed

Lines changed: 279 additions & 13 deletions

File tree

providers/flagd/flagd_evaluator.wasm

100644100755
-47.4 KB
Binary file not shown.

providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/InProcessWasmResolver.java

Lines changed: 260 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
import com.dylibso.chicory.runtime.ExportFunction;
99
import com.dylibso.chicory.runtime.HostFunction;
1010
import com.dylibso.chicory.runtime.Instance;
11+
import com.dylibso.chicory.runtime.Machine;
1112
import com.dylibso.chicory.runtime.Memory;
1213
import com.dylibso.chicory.runtime.Store;
1314
import com.dylibso.chicory.wasm.Parser;
15+
import com.dylibso.chicory.wasm.WasmModule;
1416
import com.dylibso.chicory.wasm.types.FunctionType;
1517
import com.dylibso.chicory.wasm.types.ValType;
1618
import com.dylibso.chicory.wasm.types.ValueType;
@@ -48,6 +50,7 @@
4850
import java.util.List;
4951
import java.util.Map;
5052
import java.util.function.Consumer;
53+
import java.util.function.Function;
5154
import lombok.extern.slf4j.Slf4j;
5255
import org.apache.commons.lang3.StringUtils;
5356

@@ -59,6 +62,7 @@
5962
@Slf4j
6063
public class InProcessWasmResolver implements Resolver {
6164

65+
private static final Function<Instance, Machine> MACHINE_FUNCTION;
6266
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
6367
private final Consumer<FlagdProviderEvent> onConnectionEvent;
6468
private final String scope;
@@ -69,9 +73,19 @@ public class InProcessWasmResolver implements Resolver {
6973
private ExportFunction evaluate;
7074
private ExportFunction dealloc;
7175
private Memory memory;
76+
private static final WasmModule WASM_MODULE;
7277

7378
static {
74-
79+
byte[] wasmBytes = null;
80+
try {
81+
wasmBytes = Files.readAllBytes(Path.of("flagd_evaluator.wasm"));
82+
} catch (IOException e) {
83+
throw new RuntimeException(e);
84+
}
85+
WASM_MODULE = Parser.parse(wasmBytes);
86+
MACHINE_FUNCTION = MachineFactoryCompiler.builder(WASM_MODULE)
87+
.withInterpreterFallback(InterpreterFallback.WARN)
88+
.compile();
7589
}
7690

7791
/**
@@ -89,18 +103,34 @@ public InProcessWasmResolver(FlagdOptions options, Consumer<FlagdProviderEvent>
89103
this.scope = options.getSelector();
90104

91105
var store = new Store();
92-
store.addFunction(createDescribe(),
93-
createExternrefTableGrow(), createExternrefTableSetNull(), createGetRandomValues(),
94-
createObjectDropRef());
106+
store.addFunction(
107+
createDescribe(),
108+
createExternrefTableGrow(),
109+
createExternrefTableSetNull(),
110+
createGetRandomValues(),
111+
createObjectDropRef(),
112+
createNew0(),
113+
createGetTime(),
114+
createWbindgenThrow(),
115+
createWbindgenRethrow(),
116+
createWbindgenMemory(),
117+
createWbindgenIsUndefined(),
118+
createWbindgenStringNew(),
119+
createWbindgenNumberGet(),
120+
createWbindgenBooleanGet(),
121+
createWbindgenIsNull(),
122+
createWbindgenIsObject(),
123+
createWbindgenIsString(),
124+
createWbindgenObjectCloneRef(),
125+
createWbindgenJsvalEq(),
126+
createWbindgenError()
127+
);
95128

96-
byte[] wasmBytes = null;
97-
try {
98-
wasmBytes = Files.readAllBytes(Path.of("flagd_evaluator.wasm"));
99-
} catch (IOException e) {
100-
throw new RuntimeException(e);
101-
}
102-
var module = Parser.parse(wasmBytes);
103-
var instance = Instance.builder(module).withImportValues(store.toImportValues()).build();
129+
var instance = Instance.builder(WASM_MODULE)
130+
.withImportValues(store.toImportValues())
131+
.withMachineFactory(
132+
MACHINE_FUNCTION)
133+
.build();
104134
updateStore = instance.export("update_state");
105135
evaluate = instance.export("evaluate");
106136
validationMode = instance.export("set_validation_mode");
@@ -142,7 +172,7 @@ public void init() throws Exception {
142172
var flagsChangedResponse = OBJECT_MAPPER.readValue(result,
143173
FlagsChangedResponse.class);
144174

145-
if(flagsChangedResponse.isSuccess()) {
175+
if (flagsChangedResponse.isSuccess()) {
146176
onConnectionEvent.accept(new FlagdProviderEvent(
147177
ProviderEvent.PROVIDER_CONFIGURATION_CHANGED,
148178
flagsChangedResponse.getChangedFlags(),
@@ -405,4 +435,221 @@ private static HostFunction createExternrefTableSetNull() {
405435
);
406436
}
407437

438+
private static HostFunction createNew0() {
439+
return new HostFunction(
440+
"__wbindgen_placeholder__",
441+
"__wbg_new_0_23cedd11d9b40c9d",
442+
FunctionType.of(
443+
List.of(),
444+
List.of(ValType.I32)
445+
),
446+
(Instance instance, long... args) -> {
447+
// Return a dummy reference
448+
return new long[] {0L};
449+
}
450+
);
451+
}
452+
453+
private static HostFunction createGetTime() {
454+
return new HostFunction(
455+
"__wbindgen_placeholder__",
456+
"__wbg_getTime_ad1e9878a735af08",
457+
FunctionType.of(
458+
List.of(ValType.I32),
459+
List.of(ValType.F64)
460+
),
461+
(Instance instance, long... args) -> {
462+
// Return current time in milliseconds
463+
return new long[] {Double.doubleToRawLongBits((double) System.currentTimeMillis())};
464+
}
465+
);
466+
}
467+
468+
private static HostFunction createWbindgenThrow() {
469+
return new HostFunction(
470+
"__wbindgen_placeholder__",
471+
"__wbg___wbindgen_throw_dd24417ed36fc46e",
472+
FunctionType.of(
473+
List.of(ValType.I32, ValType.I32),
474+
List.of()
475+
),
476+
(Instance instance, long... args) -> {
477+
// Throw exception - read the error message from memory
478+
int ptr = (int) args[0];
479+
int len = (int) args[1];
480+
Memory memory = instance.memory();
481+
String message = memory.readString(ptr, len);
482+
throw new RuntimeException("WASM threw: " + message);
483+
}
484+
);
485+
}
486+
487+
private static HostFunction createWbindgenRethrow() {
488+
return new HostFunction(
489+
"__wbindgen_placeholder__",
490+
"__wbindgen_rethrow",
491+
FunctionType.of(
492+
List.of(ValType.I32),
493+
List.of()
494+
),
495+
(Instance instance, long... args) -> {
496+
throw new RuntimeException("WASM rethrow");
497+
}
498+
);
499+
}
500+
501+
private static HostFunction createWbindgenMemory() {
502+
return new HostFunction(
503+
"__wbindgen_placeholder__",
504+
"__wbindgen_memory",
505+
FunctionType.of(
506+
List.of(),
507+
List.of(ValType.I32)
508+
),
509+
(Instance instance, long... args) -> {
510+
return new long[] {0L};
511+
}
512+
);
513+
}
514+
515+
private static HostFunction createWbindgenIsUndefined() {
516+
return new HostFunction(
517+
"__wbindgen_placeholder__",
518+
"__wbindgen_is_undefined",
519+
FunctionType.of(
520+
List.of(ValType.I32),
521+
List.of(ValType.I32)
522+
),
523+
(Instance instance, long... args) -> {
524+
return new long[] {0L};
525+
}
526+
);
527+
}
528+
529+
private static HostFunction createWbindgenStringNew() {
530+
return new HostFunction(
531+
"__wbindgen_placeholder__",
532+
"__wbindgen_string_new",
533+
FunctionType.of(
534+
List.of(ValType.I32, ValType.I32),
535+
List.of(ValType.I32)
536+
),
537+
(Instance instance, long... args) -> {
538+
return new long[] {0L};
539+
}
540+
);
541+
}
542+
543+
private static HostFunction createWbindgenNumberGet() {
544+
return new HostFunction(
545+
"__wbindgen_placeholder__",
546+
"__wbindgen_number_get",
547+
FunctionType.of(
548+
List.of(ValType.I32, ValType.I32),
549+
List.of()
550+
),
551+
(Instance instance, long... args) -> {
552+
return null;
553+
}
554+
);
555+
}
556+
557+
private static HostFunction createWbindgenBooleanGet() {
558+
return new HostFunction(
559+
"__wbindgen_placeholder__",
560+
"__wbindgen_boolean_get",
561+
FunctionType.of(
562+
List.of(ValType.I32),
563+
List.of(ValType.I32)
564+
),
565+
(Instance instance, long... args) -> {
566+
return new long[] {0L};
567+
}
568+
);
569+
}
570+
571+
private static HostFunction createWbindgenIsNull() {
572+
return new HostFunction(
573+
"__wbindgen_placeholder__",
574+
"__wbindgen_is_null",
575+
FunctionType.of(
576+
List.of(ValType.I32),
577+
List.of(ValType.I32)
578+
),
579+
(Instance instance, long... args) -> {
580+
return new long[] {0L};
581+
}
582+
);
583+
}
584+
585+
private static HostFunction createWbindgenIsObject() {
586+
return new HostFunction(
587+
"__wbindgen_placeholder__",
588+
"__wbindgen_is_object",
589+
FunctionType.of(
590+
List.of(ValType.I32),
591+
List.of(ValType.I32)
592+
),
593+
(Instance instance, long... args) -> {
594+
return new long[] {0L};
595+
}
596+
);
597+
}
598+
599+
private static HostFunction createWbindgenIsString() {
600+
return new HostFunction(
601+
"__wbindgen_placeholder__",
602+
"__wbindgen_is_string",
603+
FunctionType.of(
604+
List.of(ValType.I32),
605+
List.of(ValType.I32)
606+
),
607+
(Instance instance, long... args) -> {
608+
return new long[] {0L};
609+
}
610+
);
611+
}
612+
613+
private static HostFunction createWbindgenObjectCloneRef() {
614+
return new HostFunction(
615+
"__wbindgen_placeholder__",
616+
"__wbindgen_object_clone_ref",
617+
FunctionType.of(
618+
List.of(ValType.I32),
619+
List.of(ValType.I32)
620+
),
621+
(Instance instance, long... args) -> {
622+
return new long[] {args[0]};
623+
}
624+
);
625+
}
626+
627+
private static HostFunction createWbindgenJsvalEq() {
628+
return new HostFunction(
629+
"__wbindgen_placeholder__",
630+
"__wbindgen_jsval_eq",
631+
FunctionType.of(
632+
List.of(ValType.I32, ValType.I32),
633+
List.of(ValType.I32)
634+
),
635+
(Instance instance, long... args) -> {
636+
return new long[] {args[0] == args[1] ? 1L : 0L};
637+
}
638+
);
639+
}
640+
641+
private static HostFunction createWbindgenError() {
642+
return new HostFunction(
643+
"__wbindgen_placeholder__",
644+
"__wbindgen_error_new",
645+
FunctionType.of(
646+
List.of(ValType.I32, ValType.I32),
647+
List.of(ValType.I32)
648+
),
649+
(Instance instance, long... args) -> {
650+
return new long[] {0L};
651+
}
652+
);
653+
}
654+
408655
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package dev.openfeature.contrib.providers.flagd.resolver.process;
2+
3+
import dev.openfeature.contrib.providers.flagd.FlagdOptions;
4+
import org.junit.jupiter.api.Test;
5+
6+
public class WasmResolverTest {
7+
8+
@Test
9+
public void testWasmResolverInit() throws Exception {
10+
System.out.println("Creating InProcessWasmResolver...");
11+
FlagdOptions options = FlagdOptions.builder()
12+
.offlineFlagSourcePath("test.json")
13+
.build();
14+
15+
InProcessWasmResolver resolver = new InProcessWasmResolver(options, event -> {});
16+
System.out.println("InProcessWasmResolver created successfully!");
17+
resolver.init();
18+
}
19+
}

0 commit comments

Comments
 (0)