mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-21 16:04:09 -08:00
DirectMalloc intrinsic
This commit is contained in:
parent
acb4caa358
commit
7d8f5fc9c4
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2024 lax1dude.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.backend.wasm.intrinsics.gc;
|
||||
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
|
||||
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||
import org.teavm.backend.wasm.model.expression.WasmCopy;
|
||||
import org.teavm.backend.wasm.model.expression.WasmExpression;
|
||||
import org.teavm.backend.wasm.model.expression.WasmFill;
|
||||
import org.teavm.backend.wasm.model.expression.WasmInt32Constant;
|
||||
import org.teavm.backend.wasm.model.expression.WasmUnreachable;
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.DirectMalloc;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.runtime.LaxMalloc;
|
||||
|
||||
public class DirectMallocIntrinsic implements WasmIntrinsic {
|
||||
private static final MethodReference LAX_MALLOC = new MethodReference(LaxMalloc.class, "laxMalloc", int.class,
|
||||
Address.class);
|
||||
private static final MethodReference LAX_CALLOC = new MethodReference(LaxMalloc.class, "laxCalloc", int.class,
|
||||
Address.class);
|
||||
private static final MethodReference LAX_FREE = new MethodReference(LaxMalloc.class, "laxFree", Address.class,
|
||||
void.class);
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(MethodReference methodReference) {
|
||||
if (!methodReference.getClassName().equals(DirectMalloc.class.getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (methodReference.getName()) {
|
||||
case "malloc":
|
||||
case "calloc":
|
||||
case "free":
|
||||
case "memcpy":
|
||||
case "memset":
|
||||
case "zmemset":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public WasmExpression apply(InvocationExpr invocation, WasmIntrinsicManager manager) {
|
||||
switch (invocation.getMethod().getName()) {
|
||||
case "malloc": {
|
||||
var function = manager.getFunctions().forStaticMethod(LAX_MALLOC);
|
||||
var call = new WasmCall(function);
|
||||
call.getArguments().add(manager.generate(invocation.getArguments().get(0)));
|
||||
return call;
|
||||
}
|
||||
case "calloc": {
|
||||
var function = manager.getFunctions().forStaticMethod(LAX_CALLOC);
|
||||
var call = new WasmCall(function);
|
||||
call.getArguments().add(manager.generate(invocation.getArguments().get(0)));
|
||||
return call;
|
||||
}
|
||||
case "free": {
|
||||
var function = manager.getFunctions().forStaticMethod(LAX_FREE);
|
||||
var call = new WasmCall(function);
|
||||
call.getArguments().add(manager.generate(invocation.getArguments().get(0)));
|
||||
return call;
|
||||
}
|
||||
case "memcpy": {
|
||||
var copy = new WasmCopy();
|
||||
copy.setDestinationIndex(manager.generate(invocation.getArguments().get(0)));
|
||||
copy.setSourceIndex(manager.generate(invocation.getArguments().get(1)));
|
||||
copy.setCount(manager.generate(invocation.getArguments().get(2)));
|
||||
return copy;
|
||||
}
|
||||
case "memset": {
|
||||
var fill = new WasmFill();
|
||||
fill.setIndex(manager.generate(invocation.getArguments().get(0)));
|
||||
fill.setValue(manager.generate(invocation.getArguments().get(1)));
|
||||
fill.setCount(manager.generate(invocation.getArguments().get(2)));
|
||||
return fill;
|
||||
}
|
||||
case "zmemset": {
|
||||
var fill = new WasmFill();
|
||||
fill.setIndex(manager.generate(invocation.getArguments().get(0)));
|
||||
fill.setValue(new WasmInt32Constant(0));
|
||||
fill.setCount(manager.generate(invocation.getArguments().get(1)));
|
||||
return fill;
|
||||
}
|
||||
default:
|
||||
return new WasmUnreachable();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
package org.teavm.runtime;
|
||||
|
||||
import org.teavm.interop.Address;
|
||||
import org.teavm.interop.DirectMalloc;
|
||||
import org.teavm.interop.Import;
|
||||
import org.teavm.interop.StaticInit;
|
||||
import org.teavm.interop.Unmanaged;
|
||||
|
@ -51,7 +52,7 @@ public final class LaxMalloc {
|
|||
|
||||
static {
|
||||
// zero out the control region
|
||||
Allocator.fillZero(Address.fromInt(0), ADDR_HEAP_DATA_START);
|
||||
DirectMalloc.zmemset(Address.fromInt(0), ADDR_HEAP_DATA_START);
|
||||
// initialize heap limit
|
||||
Address.fromInt(ADDR_HEAP_INNER_LIMIT).putInt(ADDR_HEAP_DATA_START);
|
||||
Address.fromInt(ADDR_HEAP_OUTER_LIMIT).putInt(0x10000);
|
||||
|
@ -160,7 +161,7 @@ public final class LaxMalloc {
|
|||
|
||||
// clear if requested
|
||||
if(cleared) {
|
||||
Allocator.fillZero(ret, sizeBytes);
|
||||
DirectMalloc.zmemset(ret, sizeBytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -175,7 +176,7 @@ public final class LaxMalloc {
|
|||
|
||||
// clear if requested
|
||||
if(cleared) {
|
||||
Allocator.fillZero(ret, sizeBytes);
|
||||
DirectMalloc.zmemset(ret, sizeBytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -203,7 +204,7 @@ public final class LaxMalloc {
|
|||
|
||||
// clear if requested
|
||||
if(cleared) {
|
||||
Allocator.fillZero(ret, sizeBytes);
|
||||
DirectMalloc.zmemset(ret, sizeBytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -254,7 +255,7 @@ public final class LaxMalloc {
|
|||
|
||||
// clear if requested
|
||||
if(cleared) {
|
||||
Allocator.fillZero(ret, sizeBytes);
|
||||
DirectMalloc.zmemset(ret, sizeBytes);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright 2024 lax1dude.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.interop;
|
||||
|
||||
/**
|
||||
* Linear memory allocator for creating "direct buffers" in WASM GC<br><br>
|
||||
*
|
||||
* DO NOT USE IN LEGACY WASM BACKEND!!! Make a regular byte array, and use Address.ofData()<br><br>
|
||||
*
|
||||
* Similar to dlmalloc and emmalloc (emscripten's malloc)<br><br>
|
||||
*
|
||||
* bad things will happen if you free an address that was never allocated
|
||||
*
|
||||
* @author lax1dude
|
||||
*/
|
||||
public class DirectMalloc {
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native Address malloc(int sizeBytes);
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native Address calloc(int sizeBytes);
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native void free(Address ptr);
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native void memcpy(Address dst, Address src, int count);
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native void memset(Address ptr, int val, int count);
|
||||
|
||||
@UnsupportedOn({Platforms.JAVASCRIPT, Platforms.WEBASSEMBLY, Platforms.C})
|
||||
public static native void zmemset(Address ptr, int count);
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user