mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14: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;
|
package org.teavm.runtime;
|
||||||
|
|
||||||
import org.teavm.interop.Address;
|
import org.teavm.interop.Address;
|
||||||
|
import org.teavm.interop.DirectMalloc;
|
||||||
import org.teavm.interop.Import;
|
import org.teavm.interop.Import;
|
||||||
import org.teavm.interop.StaticInit;
|
import org.teavm.interop.StaticInit;
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
|
@ -51,7 +52,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// zero out the control region
|
// 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
|
// initialize heap limit
|
||||||
Address.fromInt(ADDR_HEAP_INNER_LIMIT).putInt(ADDR_HEAP_DATA_START);
|
Address.fromInt(ADDR_HEAP_INNER_LIMIT).putInt(ADDR_HEAP_DATA_START);
|
||||||
Address.fromInt(ADDR_HEAP_OUTER_LIMIT).putInt(0x10000);
|
Address.fromInt(ADDR_HEAP_OUTER_LIMIT).putInt(0x10000);
|
||||||
|
@ -160,7 +161,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
// clear if requested
|
// clear if requested
|
||||||
if(cleared) {
|
if(cleared) {
|
||||||
Allocator.fillZero(ret, sizeBytes);
|
DirectMalloc.zmemset(ret, sizeBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -175,7 +176,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
// clear if requested
|
// clear if requested
|
||||||
if(cleared) {
|
if(cleared) {
|
||||||
Allocator.fillZero(ret, sizeBytes);
|
DirectMalloc.zmemset(ret, sizeBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -203,7 +204,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
// clear if requested
|
// clear if requested
|
||||||
if(cleared) {
|
if(cleared) {
|
||||||
Allocator.fillZero(ret, sizeBytes);
|
DirectMalloc.zmemset(ret, sizeBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -254,7 +255,7 @@ public final class LaxMalloc {
|
||||||
|
|
||||||
// clear if requested
|
// clear if requested
|
||||||
if(cleared) {
|
if(cleared) {
|
||||||
Allocator.fillZero(ret, sizeBytes);
|
DirectMalloc.zmemset(ret, sizeBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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