package com.oracle.truffle.js.test.instrumentation;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.BuiltinRootTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.LiteralTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.ObjectAllocationTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.ReadPropertyTag;
import com.oracle.truffle.js.nodes.instrumentation.JSTags.WritePropertyTag;
import com.oracle.truffle.js.runtime.builtins.JSArray;
import com.oracle.truffle.js.runtime.builtins.JSFunction;
import com.oracle.truffle.js.runtime.objects.JSDynamicObject;
public class ObjectAllocationTest extends FineGrainedAccessTest {
@Test
public void basic() {
evalAllTags("var a = new Object(); var b = {}; var c = [];");
enter(WritePropertyTag.class, (e, write) -> {
assertAttribute(e, KEY, "a");
write.input(assertGlobalObjectInput);
enter(ObjectAllocationTag.class, (e1, alloc) -> {
enter(ReadPropertyTag.class).input(assertGlobalObjectInput).exit();
alloc.input((e2) -> {
assertTrue(JSFunction.isJSFunction(e2.val));
});
enter(BuiltinRootTag.class, (e2) -> {
assertAttribute(e2, NAME, "Object");
}).exit();
}).exit();
write.input((e1) -> {
assertTrue(JSDynamicObject.isJSDynamicObject(e1.val));
});
}).exit();
enter(WritePropertyTag.class, (e, prop) -> {
assertAttribute(e, KEY, "b");
prop.input(assertGlobalObjectInput);
enter(LiteralTag.class).exit();
prop.input((e1) -> {
assertTrue(JSDynamicObject.isJSDynamicObject(e1.val));
});
}).exit();
enter(WritePropertyTag.class, (e, prop) -> {
assertAttribute(e, KEY, "c");
prop.input(assertGlobalObjectInput);
enter(LiteralTag.class).exit();
prop.input((e1) -> {
assertTrue(JSArray.isJSArray(e1.val));
});
}).exit();
}
@Test
public void nested() {
evalAllTags("var a = {x:{}}; var b = [[]]; var c = {x:[]}");
enter(WritePropertyTag.class, (e, prop) -> {
assertAttribute(e, KEY, "a");
prop.input(assertGlobalObjectInput);
enter(LiteralTag.class, (e1, lit) -> {
assertAttribute(e1, LITERAL_TYPE, LiteralTag.Type.ObjectLiteral.name());
enter(LiteralTag.class, (e2) -> {
assertAttribute(e2, LITERAL_TYPE, LiteralTag.Type.ObjectLiteral.name());
}).exit();
lit.input((e2) -> {
assertTrue(JSDynamicObject.isJSDynamicObject(e2.val));
});
}).exit();
prop.input((e1) -> {
assertTrue(JSDynamicObject.isJSDynamicObject(e1.val));
});
}).exit();
enter(WritePropertyTag.class, (e, prop) -> {
assertAttribute(e, KEY, "b");
prop.input(assertGlobalObjectInput);
enter(LiteralTag.class, (e1, lit) -> {
assertAttribute(e1, LITERAL_TYPE, LiteralTag.Type.ArrayLiteral.name());
enter(LiteralTag.class, (e2) -> {
assertAttribute(e2, LITERAL_TYPE, LiteralTag.Type.ArrayLiteral.name());
}).exit();
lit.input((e2) -> {
assertTrue(JSArray.isJSArray(e2.val));
});
}).exit();
prop.input((e1) -> {
assertTrue(JSArray.isJSArray(e1.val));
});
}).exit();
enter(WritePropertyTag.class, (e, prop) -> {
assertAttribute(e, KEY, "c");
prop.input(assertGlobalObjectInput);
enter(LiteralTag.class, (e1, lit) -> {
assertAttribute(e1, LITERAL_TYPE, LiteralTag.Type.ObjectLiteral.name());
enter(LiteralTag.class, (e2) -> {
assertAttribute(e2, LITERAL_TYPE, LiteralTag.Type.ArrayLiteral.name());
}).exit();
lit.input((e2) -> {
assertTrue(JSArray.isJSArray(e2.val));
});
}).exit();
prop.input((e1) -> {
assertTrue(JSDynamicObject.isJSDynamicObject(e1.val));
});
}).exit();
}
}