mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
experimental code for arrays
This commit is contained in:
parent
8f365d629b
commit
74dcb4dc09
@ -31,6 +31,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import de.inetsoftware.classparser.Member;
|
import de.inetsoftware.classparser.Member;
|
||||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||||
|
import de.inetsoftware.jwebassembly.module.ArrayOperator;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||||
@ -778,4 +779,30 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
throw new Error( "Unknown block: " + op );
|
throw new Error( "Unknown block: " + op );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException {
|
||||||
|
int opCode;
|
||||||
|
switch(op) {
|
||||||
|
case NEW:
|
||||||
|
opCode = ARRAY_NEW;
|
||||||
|
break;
|
||||||
|
case GET:
|
||||||
|
opCode = ARRAY_GET;
|
||||||
|
break;
|
||||||
|
case SET:
|
||||||
|
opCode = ARRAY_SET;
|
||||||
|
break;
|
||||||
|
case LENGTH:
|
||||||
|
opCode = ARRAY_LEN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error( "Unknown operator: " + op );
|
||||||
|
}
|
||||||
|
codeStream.writeOpCode( opCode );
|
||||||
|
codeStream.writeValueType( valueType );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,4 +396,23 @@ interface InstructionOpcodes {
|
|||||||
static final int I64_TRUNC_S_SAT_F64 = 0xFC06;
|
static final int I64_TRUNC_S_SAT_F64 = 0xFC06;
|
||||||
|
|
||||||
static final int I64_TRUNC_U_SAT_F64 = 0xFC07;
|
static final int I64_TRUNC_U_SAT_F64 = 0xFC07;
|
||||||
|
|
||||||
|
// === GC opcodes (unofficial, experimental) ===== https://github.com/lars-t-hansen/moz-gc-experiments/blob/master/version2.md
|
||||||
|
|
||||||
|
static final int STRUCT_NEW = 0xFC50;
|
||||||
|
|
||||||
|
static final int STRUCT_GET = 0xFC51;
|
||||||
|
|
||||||
|
static final int STRUCT_SET = 0xFC52;
|
||||||
|
|
||||||
|
static final int STRUCT_NARROW = 0xFC53;
|
||||||
|
|
||||||
|
|
||||||
|
static final int ARRAY_NEW = 0xFC60;
|
||||||
|
|
||||||
|
static final int ARRAY_GET = 0xFC61;
|
||||||
|
|
||||||
|
static final int ARRAY_SET = 0xFC62;
|
||||||
|
|
||||||
|
static final int ARRAY_LEN = 0xFC63;
|
||||||
}
|
}
|
||||||
|
29
src/de/inetsoftware/jwebassembly/module/ArrayOperator.java
Normal file
29
src/de/inetsoftware/jwebassembly/module/ArrayOperator.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Volker Berlin (i-net software)
|
||||||
|
|
||||||
|
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 de.inetsoftware.jwebassembly.module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operation on Arrays.
|
||||||
|
*
|
||||||
|
* @author Volker Berlin
|
||||||
|
*/
|
||||||
|
public enum ArrayOperator {
|
||||||
|
NEW,
|
||||||
|
GET,
|
||||||
|
SET,
|
||||||
|
LENGTH,
|
||||||
|
}
|
@ -131,7 +131,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
case 24: // dload
|
case 24: // dload
|
||||||
addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedByte(), codePos );
|
addLoadStoreInstruction( ValueType.f64, true, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 25: // aload
|
case 25: // aload
|
||||||
|
addLoadStoreInstruction( ValueType.anyref, true, byteCode.readUnsignedByte(), codePos );
|
||||||
|
break;
|
||||||
case 26: // iload_0
|
case 26: // iload_0
|
||||||
case 27: // iload_1
|
case 27: // iload_1
|
||||||
case 28: // iload_2
|
case 28: // iload_2
|
||||||
@ -156,11 +158,15 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
case 41: // dload_3
|
case 41: // dload_3
|
||||||
addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos );
|
addLoadStoreInstruction( ValueType.f64, true, op - 38, codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 42: //aload_0
|
case 42: //aload_0
|
||||||
//TODO case 43: //aload_1
|
case 43: //aload_1
|
||||||
//TODO case 44: //aload_2
|
case 44: //aload_2
|
||||||
//TODO case 45: //aload_3
|
case 45: //aload_3
|
||||||
//TODO case 46: // iaload
|
addLoadStoreInstruction( ValueType.anyref, true, op - 42, codePos );
|
||||||
|
break;
|
||||||
|
case 46: // iaload
|
||||||
|
addArrayInstruction( ArrayOperator.GET, ValueType.i32, codePos );
|
||||||
|
break;
|
||||||
//TODO case 47: // laload
|
//TODO case 47: // laload
|
||||||
//TODO case 48: // faload
|
//TODO case 48: // faload
|
||||||
//TODO case 49: // daload
|
//TODO case 49: // daload
|
||||||
@ -180,7 +186,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
case 57: // dstore
|
case 57: // dstore
|
||||||
addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedByte(), codePos );
|
addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedByte(), codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 58: // astore
|
case 58: // astore
|
||||||
|
addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedByte(), codePos );
|
||||||
|
break;
|
||||||
case 59: // istore_0
|
case 59: // istore_0
|
||||||
case 60: // istore_1
|
case 60: // istore_1
|
||||||
case 61: // istore_2
|
case 61: // istore_2
|
||||||
@ -211,14 +219,16 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
case 78: // astore_3
|
case 78: // astore_3
|
||||||
addLoadStoreInstruction( ValueType.anyref, false, op - 75, codePos );
|
addLoadStoreInstruction( ValueType.anyref, false, op - 75, codePos );
|
||||||
break;
|
break;
|
||||||
//TODO case 79: // iastore
|
case 79: // iastore
|
||||||
//TODO case 80: // lastore
|
addArrayInstruction( ArrayOperator.SET, ValueType.i32, codePos );
|
||||||
//TODO case 81: // fastore
|
break;
|
||||||
//TODO case 82: // dastore
|
//TODO case 80: // lastore
|
||||||
//TODO case 83: // aastore
|
//TODO case 81: // fastore
|
||||||
//TODO case 84: // bastore
|
//TODO case 82: // dastore
|
||||||
//TODO case 85: // castore
|
//TODO case 83: // aastore
|
||||||
//TODO case 86: // sastore
|
//TODO case 84: // bastore
|
||||||
|
//TODO case 85: // castore
|
||||||
|
//TODO case 86: // sastore
|
||||||
case 87: // pop
|
case 87: // pop
|
||||||
case 88: // pop2
|
case 88: // pop2
|
||||||
addBlockInstruction( WasmBlockOperator.DROP, null, codePos );
|
addBlockInstruction( WasmBlockOperator.DROP, null, codePos );
|
||||||
@ -238,6 +248,9 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
case f64:
|
case f64:
|
||||||
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_f64", "(D)DD" ), codePos );
|
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_f64", "(D)DD" ), codePos );
|
||||||
break OP;
|
break OP;
|
||||||
|
case anyref:
|
||||||
|
addCallInstruction( new SyntheticMember( "de/inetsoftware/jwebassembly/module/NativeHelperCode", "dup_anyref", "(Ljava.lang.Object;)Ljava.lang.Object;Ljava.lang.Object;" ), codePos );
|
||||||
|
break OP;
|
||||||
}
|
}
|
||||||
//$FALL-THROUGH$
|
//$FALL-THROUGH$
|
||||||
case 90: // dup_x1
|
case 90: // dup_x1
|
||||||
@ -518,9 +531,36 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
|
|||||||
//TODO case 185: // invokeinterface
|
//TODO case 185: // invokeinterface
|
||||||
//TODO case 186: // invokedynamic
|
//TODO case 186: // invokedynamic
|
||||||
//TODO case 187: // new
|
//TODO case 187: // new
|
||||||
//TODO case 188: // newarray
|
case 188: // newarray
|
||||||
|
int typeValue = byteCode.readByte();
|
||||||
|
switch( typeValue ) {
|
||||||
|
case 4: // boolean
|
||||||
|
case 5: // char
|
||||||
|
type = ValueType.i32;
|
||||||
|
break;
|
||||||
|
case 6: //float
|
||||||
|
type = ValueType.f32;
|
||||||
|
break;
|
||||||
|
case 7: //double
|
||||||
|
type = ValueType.f64;
|
||||||
|
break;
|
||||||
|
case 8: //byte
|
||||||
|
case 9: //short
|
||||||
|
case 10: //int
|
||||||
|
type = ValueType.i32;
|
||||||
|
break;
|
||||||
|
case 11: //long
|
||||||
|
type = ValueType.i64;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new WasmException( "Invalid Java byte code newarray: " + typeValue, byteCode.getLineNumber() );
|
||||||
|
}
|
||||||
|
addArrayInstruction( ArrayOperator.NEW, type, codePos );
|
||||||
|
break;
|
||||||
//TODO case 189: // anewarray
|
//TODO case 189: // anewarray
|
||||||
//TODO case 190: // arraylength
|
case 190: // arraylength
|
||||||
|
addArrayInstruction( ArrayOperator.LENGTH, ValueType.i32, codePos );
|
||||||
|
break;
|
||||||
//TODO case 191: // athrow
|
//TODO case 191: // athrow
|
||||||
//TODO case 192: // checkcast
|
//TODO case 192: // checkcast
|
||||||
//TODO case 193: // instanceof
|
//TODO case 193: // instanceof
|
||||||
|
@ -203,4 +203,16 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
protected abstract void writeBlockCode( @Nonnull WasmBlockOperator op, @Nullable Object data ) throws IOException;
|
protected abstract void writeBlockCode( @Nonnull WasmBlockOperator op, @Nullable Object data ) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an array operation.
|
||||||
|
*
|
||||||
|
* @param op
|
||||||
|
* the operation
|
||||||
|
* @param valueType
|
||||||
|
* the resulting type
|
||||||
|
* @throws IOException
|
||||||
|
* if any I/O error occur
|
||||||
|
*/
|
||||||
|
protected abstract void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -30,4 +30,7 @@ public class NativeHelperCode {
|
|||||||
|
|
||||||
@WasmTextCode( signature = "(D)DD", value = "get_local 0 get_local 0 return" )
|
@WasmTextCode( signature = "(D)DD", value = "get_local 0 get_local 0 return" )
|
||||||
native static void dup_f64();
|
native static void dup_f64();
|
||||||
|
|
||||||
|
@WasmTextCode( signature = "(Ljava.lang.Object;)Ljava.lang.Object;Ljava.lang.Object;", value = "get_local 0 get_local 0 return" )
|
||||||
|
native static void dup_anyref();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Volker Berlin (i-net software)
|
||||||
|
|
||||||
|
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 de.inetsoftware.jwebassembly.module;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WasmInstruction for numeric operation.
|
||||||
|
*
|
||||||
|
* @author Volker Berlin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class WasmArrayInstruction extends WasmInstruction {
|
||||||
|
|
||||||
|
private final ArrayOperator op;
|
||||||
|
|
||||||
|
private final ValueType valueType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an instance of numeric operation.
|
||||||
|
*
|
||||||
|
* @param numOp
|
||||||
|
* the numeric operation
|
||||||
|
* @param valueType
|
||||||
|
* the type of the parameters
|
||||||
|
* @param javaCodePos
|
||||||
|
* the code position/offset in the Java method
|
||||||
|
*/
|
||||||
|
WasmArrayInstruction( @Nullable ArrayOperator op, @Nullable ValueType valueType, int javaCodePos ) {
|
||||||
|
super( javaCodePos );
|
||||||
|
this.op = op;
|
||||||
|
this.valueType = valueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public void writeTo( @Nonnull ModuleWriter writer ) throws IOException {
|
||||||
|
writer.writeArrayOperator( op, valueType );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
ValueType getPushValueType() {
|
||||||
|
switch( op ) {
|
||||||
|
case NEW:
|
||||||
|
return ValueType.anyref;
|
||||||
|
case GET:
|
||||||
|
return valueType;
|
||||||
|
case SET:
|
||||||
|
return null;
|
||||||
|
case LENGTH:
|
||||||
|
return ValueType.i32;
|
||||||
|
default:
|
||||||
|
throw new WasmException( "Unknown array operation: " + op, -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
int getPopCount() {
|
||||||
|
switch( op ) {
|
||||||
|
case NEW:
|
||||||
|
case GET:
|
||||||
|
case LENGTH:
|
||||||
|
return 1;
|
||||||
|
case SET:
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
throw new WasmException( "Unknown array operation: " + op, -1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -205,4 +205,18 @@ public abstract class WasmCodeBuilder {
|
|||||||
protected void addNopInstruction( int javaCodePos ) {
|
protected void addNopInstruction( int javaCodePos ) {
|
||||||
instructions.add( new WasmNopInstruction( javaCodePos ) );
|
instructions.add( new WasmNopInstruction( javaCodePos ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an array operation to the instruction list as marker on the code position.
|
||||||
|
*
|
||||||
|
* @param op
|
||||||
|
* the operation
|
||||||
|
* @param type
|
||||||
|
* the array type
|
||||||
|
* @param javaCodePos
|
||||||
|
* the code position/offset in the Java method
|
||||||
|
*/
|
||||||
|
protected void addArrayInstruction( ArrayOperator op, ValueType type, int javaCodePos ) {
|
||||||
|
instructions.add( new WasmArrayInstruction( op, type, javaCodePos ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import de.inetsoftware.classparser.Member;
|
import de.inetsoftware.classparser.Member;
|
||||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||||
|
import de.inetsoftware.jwebassembly.module.ArrayOperator;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
import de.inetsoftware.jwebassembly.module.NumericOperator;
|
||||||
@ -362,4 +363,27 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
methodOutput.append( name );
|
methodOutput.append( name );
|
||||||
inset += insetAfter;
|
inset += insetAfter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void writeArrayOperator( @Nonnull ArrayOperator op, ValueType valueType ) throws IOException {
|
||||||
|
String operation;
|
||||||
|
switch( op ) {
|
||||||
|
case NEW:
|
||||||
|
operation = "new";
|
||||||
|
break;
|
||||||
|
case GET:
|
||||||
|
operation = "get";
|
||||||
|
break;
|
||||||
|
case SET:
|
||||||
|
operation = "set";
|
||||||
|
break;
|
||||||
|
case LENGTH:
|
||||||
|
operation = "len";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error( "Unknown operator: " + op );
|
||||||
|
}
|
||||||
|
newline( methodOutput );
|
||||||
|
methodOutput.append( "array." ).append( operation ).append( ' ' ).append( valueType );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
74
test/de/inetsoftware/jwebassembly/runtime/Arrays.java
Normal file
74
test/de/inetsoftware/jwebassembly/runtime/Arrays.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Volker Berlin (i-net software)
|
||||||
|
*
|
||||||
|
* 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 de.inetsoftware.jwebassembly.runtime;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Ignore;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.ScriptEngine;
|
||||||
|
import de.inetsoftware.jwebassembly.WasmRule;
|
||||||
|
import de.inetsoftware.jwebassembly.api.annotation.Export;
|
||||||
|
|
||||||
|
public class Arrays extends AbstractBaseTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static WasmRule rule = new WasmRule( TestClass.class );
|
||||||
|
|
||||||
|
public Arrays( ScriptEngine script, String method, Object[] params ) {
|
||||||
|
super( rule, script, method, params );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Parameters( name = "{0}-{1}" )
|
||||||
|
public static Collection<Object[]> data() {
|
||||||
|
ArrayList<Object[]> list = new ArrayList<>();
|
||||||
|
for( ScriptEngine[] val : ScriptEngine.testParams() ) {
|
||||||
|
ScriptEngine script = val[0];
|
||||||
|
addParam( list, script, "length" );
|
||||||
|
addParam( list, script, "loop" );
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
super.test();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestClass {
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int length() {
|
||||||
|
return new int[5].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int loop() {
|
||||||
|
int[] data = {1,2,3};
|
||||||
|
int sum = 0;
|
||||||
|
for( int i : data ) {
|
||||||
|
sum += i;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user